summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrimio <vasi.vilvoiu@gmail.com>2019-01-08 18:30:03 +0200
committerrimio <vasi.vilvoiu@gmail.com>2019-01-08 18:30:03 +0200
commit85acad49b42bf3734249dae13429a26395a68a03 (patch)
tree01361d557a2b80752f399e27fc6f38fd0757f5f0
parenta7d5e7ca20c959b739d80f96362f326a5848cdb3 (diff)
Start encoder
-rw-r--r--CMakeLists.txt1
-rw-r--r--README.md2
-rw-r--r--src/encoder.c145
-rw-r--r--src/libsstv.template.h79
-rw-r--r--src/luts.c13
-rw-r--r--src/luts.h17
-rw-r--r--src/sstv.c29
-rw-r--r--src/tools/sstv-encode.cpp27
-rw-r--r--util/genluts.py30
-rw-r--r--util/view.py11
10 files changed, 345 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aba5559..5eda742 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,6 +35,7 @@ configure_file (
set (LIB_SOURCES
"${SRC_DIR}/sstv.c"
"${SRC_DIR}/encoder.c"
+ "${SRC_DIR}/luts.c"
)
set (ENCODE_TOOL_SOURCES
diff --git a/README.md b/README.md
index cd6e192..666fe1b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
# libsstv
-SSTV C++ encoder/decoder library.
+SSTV C encoder/decoder library for embedded systems.
diff --git a/src/encoder.c b/src/encoder.c
index 4fa059a..ecee41f 100644
--- a/src/encoder.c
+++ b/src/encoder.c
@@ -7,6 +7,24 @@
#include "sstv.h"
#include "libsstv.h"
+#include "luts.h"
+
+/*
+ * Computation helpers
+ */
+#define REMAINING_SAMPLES_US(time_us, sample_rate) ((uint64_t)(time_us) * (uint64_t)(sample_rate) / 1000000)
+#define DPHASE_FROM_FREQ(freq, sample_rate) ((uint64_t)(freq) * 65536 / (uint64_t)(sample_rate))
+
+/*
+ * Encoder state
+ */
+typedef enum {
+ SSTV_ENCODER_STATE_START,
+ SSTV_ENCODER_STATE_LEADER_TONE_1,
+ SSTV_ENCODER_STATE_BREAK,
+ SSTV_ENCODER_STATE_LEADER_TONE_2,
+ SSTV_ENCODER_STATE_END
+} sstv_encoder_state_t;
/*
* Encoder context
@@ -18,9 +36,21 @@ typedef struct {
/* output configuration */
sstv_mode_t mode;
size_t sample_rate;
+
+ /* current state */
+ sstv_encoder_state_t state;
+
+ /* current FSK value to be written */
+ struct {
+ uint16_t phase;
+ uint16_t phase_delta;
+ size_t remaining_samples;
+ } fsk;
} sstv_encoder_context_t;
-/* default encoder contexts, for when no allocation/deallocation routines are provided */
+/*
+ * Default encoder contexts, for when no allocation/deallocation routines are provided
+ */
static sstv_encoder_context_t default_encoder_context[SSTV_DEFAULT_ENCODER_CONTEXT_COUNT];
static uint64_t default_encoder_context_usage = 0x0;
@@ -70,16 +100,18 @@ sstv_create_encoder(void **out_ctx, sstv_image_t image, sstv_mode_t mode, size_t
break;
}
}
- }
-
- if (!ctx) {
- return SSTV_INTERNAL_ERROR;
+ if (!ctx) {
+ return SSTV_NO_DEFAULT_ENCODERS;
+ }
}
/* initialize context */
ctx->image = image;
ctx->mode = mode;
ctx->sample_rate = sample_rate;
+ ctx->state = SSTV_ENCODER_STATE_START;
+ ctx->fsk.phase = 0; /* start nicely from zero */
+ ctx->fsk.remaining_samples = 0; /* so we get initial state change */
/* set output */
*out_ctx = ctx;
@@ -118,7 +150,108 @@ sstv_delete_encoder(void *ctx)
return SSTV_OK;
}
+static sstv_error_t
+sstv_encode_pd_state_change(sstv_encoder_context_t *context)
+{
+ /* done */
+ return SSTV_OK;
+}
+
+static sstv_error_t
+sstv_encode_state_change(sstv_encoder_context_t *context)
+{
+ /* leader tone #1 */
+ if (context->state == SSTV_ENCODER_STATE_START) {
+ context->state = SSTV_ENCODER_STATE_LEADER_TONE_1;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1900, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(300000, context->sample_rate);
+ return SSTV_OK;
+ }
+
+ /* break */
+ if (context->state == SSTV_ENCODER_STATE_LEADER_TONE_1) {
+ context->state = SSTV_ENCODER_STATE_BREAK;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1200, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(10000, context->sample_rate);
+ return SSTV_OK;
+ }
+
+ /* leader tone #2 */
+ if (context->state == SSTV_ENCODER_STATE_BREAK) {
+ context->state = SSTV_ENCODER_STATE_LEADER_TONE_2;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1900, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(300000, context->sample_rate);
+ 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 */
+ case SSTV_MODE_PD90:
+ case SSTV_MODE_PD120:
+ case SSTV_MODE_PD160:
+ case SSTV_MODE_PD180:
+ case SSTV_MODE_PD240:
+ return sstv_encode_pd_state_change(context);
+
+ default:
+ return SSTV_BAD_MODE;
+ }
+}
+
sstv_error_t
-sstv_encode(void *ctx, uint8_t *buffer, size_t buffer_size)
+sstv_encode(void *ctx, sstv_signal_t *signal)
{
+ sstv_error_t rc;
+ sstv_encoder_context_t *context = (sstv_encoder_context_t *)ctx;
+
+ if (!context || !signal) {
+ return SSTV_BAD_PARAMETER;
+ }
+
+ /* reset signal container */
+ signal->count = 0;
+
+ /* main encoding loop */
+ while (1) {
+ /* state change? */
+ if (context->fsk.remaining_samples == 0) {
+ rc = sstv_encode_state_change(context);
+ if (rc != SSTV_OK) {
+ return rc;
+ }
+
+ /* end of encoding? */
+ if (context->state == SSTV_ENCODER_STATE_END) {
+ return SSTV_ENCODE_END;
+ }
+ continue;
+ }
+
+ /* end of buffer? */
+ if (signal->count == signal->capacity) {
+ return SSTV_ENCODE_SUCCESSFUL;
+ }
+
+ /* encode sample and continue */
+ context->fsk.remaining_samples --;
+ context->fsk.phase += context->fsk.phase_delta;
+ switch(signal->type) {
+ case SSTV_SAMPLE_INT8:
+ ((int8_t *)signal->buffer)[signal->count] = SSTV_SIN_INT10_INT8[context->fsk.phase >> 6];
+ break;
+
+ case SSTV_SAMPLE_INT16:
+ ((int16_t *)signal->buffer)[signal->count] = SSTV_SIN_INT10_INT16[context->fsk.phase >> 6];
+ break;
+
+ default:
+ return SSTV_BAD_SAMPLE_TYPE;
+ }
+ signal->count ++;
+ }
} \ No newline at end of file
diff --git a/src/libsstv.template.h b/src/libsstv.template.h
index 2a22474..ec120ef 100644
--- a/src/libsstv.template.h
+++ b/src/libsstv.template.h
@@ -42,13 +42,15 @@ typedef enum {
SSTV_BAD_MODE = 104,
SSTV_BAD_FORMAT = 105,
SSTV_BAD_RESOLUTION = 106,
+ SSTV_BAD_SAMPLE_TYPE = 107,
SSTV_ALLOC_FAIL = 200,
/* Encoder return codes */
SSTV_ENCODE_SUCCESSFUL = 1000,
SSTV_ENCODE_END = 1001,
- SSTV_ENCODE_FAIL = 1002,
+
+ SSTV_NO_DEFAULT_ENCODERS = 1100,
} sstv_error_t;
/*
@@ -96,6 +98,34 @@ typedef struct {
uint8_t *buffer;
} sstv_image_t;
+/*
+ * Signal sample type
+ */
+typedef enum {
+ SSTV_SAMPLE_INT8,
+ SSTV_SAMPLE_INT16
+} sstv_sample_type_t;
+
+/*
+ * Signal container
+ */
+typedef struct {
+ /* buffer pointer */
+ void *buffer;
+
+ /* size in bytes */
+ size_t size;
+
+ /* sample type */
+ sstv_sample_type_t type;
+
+ /* number of total samples */
+ size_t capacity;
+
+ /* number of used samples */
+ size_t count;
+} sstv_signal_t;
+
/*
* Initialize the library.
@@ -170,8 +200,53 @@ extern sstv_error_t sstv_pack_image(sstv_image_t *out_img, size_t width, size_t
*/
extern sstv_error_t sstv_delete_image(sstv_image_t *img);
+/*
+ * Pack a signal buffer into a signal structure.
+ * sig(in): signal structure to initialize
+ * type(in): sample type
+ * capacity(in): buffer capacity in sampless
+ * buffer(in): buffer pointer
+ * returns: error code
+ *
+ * NOTE: Buffer is managed by user.
+ */
+extern sstv_error_t sstv_pack_signal(sstv_signal_t *sig, sstv_sample_type_t type, size_t capacity, void *buffer);
+
+/*
+ * Create an SSTV encoder.
+ * out_ctx(out): output context structure pointer
+ * image(in): image buffer
+ * mode(in): SSTV mode
+ * sample_rate(in): output signal sample rate
+ * returns: error code
+ *
+ * NOTE: Context shall never be modified by the user.
+ * NOTE: If an allocator/deallocator is provided via sstv_init(), then the
+ * context structure will be dynamically allocated. Otherwise, one of the
+ * default (static) structures, built into the library, will be used. There are
+ * SSTV_DEFAULT_ENCODER_CONTEXT_COUNT default structures, and once these are
+ * used up, a SSTV_NO_DEFAULT_ENCODERS error is returned.
+ */
extern sstv_error_t sstv_create_encoder(void **out_ctx, sstv_image_t image, sstv_mode_t mode, size_t sample_rate);
+
+/*
+ * Deletes an SSTV encoder.
+ * ctx(in): encoder context structure pointer
+ * returns: error code
+ *
+ * NOTE: If context is one of the default encoders, then it will be marked as
+ * reusable and can be claimed again by sstv_create_encoder().
+ */
extern sstv_error_t sstv_delete_encoder(void *ctx);
-extern sstv_error_t sstv_encode(void *ctx, uint8_t *buffer, size_t buffer_size);
+
+/*
+ * Encode image into SSTV signal.
+ * ctx(in): encoder context structure pointer
+ * signal(in): output signal container
+ * returns: SSTV_ENCODE_SUCCESSFUL on successful fill of signal buffer
+ * SSTV_ENCODE_END on successful encoding of whole image
+ * error code otherwise
+ */
+extern sstv_error_t sstv_encode(void *ctx, sstv_signal_t *signal);
#endif \ No newline at end of file
diff --git a/src/luts.c b/src/luts.c
new file mode 100644
index 0000000..58ed7e9
--- /dev/null
+++ b/src/luts.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2018 Vasile Vilvoiu (YO7JBP) <vasi.vilvoiu@gmail.com>
+ *
+ * libsstv is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#include "luts.h"
+
+int8_t SSTV_SIN_INT10_INT8[1024] = { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26, 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 38, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46, 47, 48, 49, 49, 50, 51, 51, 52, 53, 54, 54, 55, 56, 56, 57, 58, 58, 59, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68, 69, 69, 70, 71, 71, 72, 72, 73, 74, 74, 75, 76, 76, 77, 78, 78, 79, 79, 80, 81, 81, 82, 82, 83, 84, 84, 85, 85, 86, 86, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 106, 107, 107, 108, 108, 109, 109, 109, 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 125, 125, 125, 125, 125, 125, 125, 124, 124, 124, 124, 124, 124, 123, 123, 123, 123, 123, 122, 122, 122, 122, 122, 121, 121, 121, 121, 120, 120, 120, 120, 119, 119, 119, 118, 118, 118, 118, 117, 117, 117, 116, 116, 116, 115, 115, 115, 114, 114, 114, 113, 113, 113, 112, 112, 112, 111, 111, 111, 110, 110, 109, 109, 109, 108, 108, 107, 107, 106, 106, 106, 105, 105, 104, 104, 103, 103, 102, 102, 102, 101, 101, 100, 100, 99, 99, 98, 98, 97, 97, 96, 96, 95, 95, 94, 94, 93, 93, 92, 91, 91, 90, 90, 89, 89, 88, 88, 87, 86, 86, 85, 85, 84, 84, 83, 82, 82, 81, 81, 80, 79, 79, 78, 78, 77, 76, 76, 75, 74, 74, 73, 72, 72, 71, 71, 70, 69, 69, 68, 67, 67, 66, 65, 65, 64, 63, 63, 62, 61, 61, 60, 59, 58, 58, 57, 56, 56, 55, 54, 54, 53, 52, 51, 51, 50, 49, 49, 48, 47, 46, 46, 45, 44, 44, 43, 42, 41, 41, 40, 39, 38, 38, 37, 36, 35, 35, 34, 33, 32, 32, 31, 30, 29, 29, 28, 27, 26, 26, 25, 24, 23, 22, 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 14, 13, 12, 12, 11, 10, 9, 9, 8, 7, 6, 5, 5, 4, 3, 2, 2, 1, 0, -1, -2, -2, -3, -4, -5, -5, -6, -7, -8, -9, -9, -10, -11, -12, -12, -13, -14, -15, -16, -16, -17, -18, -19, -19, -20, -21, -22, -22, -23, -24, -25, -26, -26, -27, -28, -29, -29, -30, -31, -32, -32, -33, -34, -35, -35, -36, -37, -38, -38, -39, -40, -41, -41, -42, -43, -44, -44, -45, -46, -46, -47, -48, -49, -49, -50, -51, -51, -52, -53, -54, -54, -55, -56, -56, -57, -58, -58, -59, -60, -61, -61, -62, -63, -63, -64, -65, -65, -66, -67, -67, -68, -69, -69, -70, -71, -71, -72, -72, -73, -74, -74, -75, -76, -76, -77, -78, -78, -79, -79, -80, -81, -81, -82, -82, -83, -84, -84, -85, -85, -86, -86, -87, -88, -88, -89, -89, -90, -90, -91, -91, -92, -93, -93, -94, -94, -95, -95, -96, -96, -97, -97, -98, -98, -99, -99, -100, -100, -101, -101, -102, -102, -102, -103, -103, -104, -104, -105, -105, -106, -106, -106, -107, -107, -108, -108, -109, -109, -109, -110, -110, -111, -111, -111, -112, -112, -112, -113, -113, -113, -114, -114, -114, -115, -115, -115, -116, -116, -116, -117, -117, -117, -118, -118, -118, -118, -119, -119, -119, -120, -120, -120, -120, -121, -121, -121, -121, -122, -122, -122, -122, -122, -123, -123, -123, -123, -123, -124, -124, -124, -124, -124, -124, -125, -125, -125, -125, -125, -125, -125, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -126, -125, -125, -125, -125, -125, -125, -125, -124, -124, -124, -124, -124, -124, -123, -123, -123, -123, -123, -122, -122, -122, -122, -122, -121, -121, -121, -121, -120, -120, -120, -120, -119, -119, -119, -118, -118, -118, -118, -117, -117, -117, -116, -116, -116, -115, -115, -115, -114, -114, -114, -113, -113, -113, -112, -112, -112, -111, -111, -111, -110, -110, -109, -109, -109, -108, -108, -107, -107, -106, -106, -106, -105, -105, -104, -104, -103, -103, -102, -102, -102, -101, -101, -100, -100, -99, -99, -98, -98, -97, -97, -96, -96, -95, -95, -94, -94, -93, -93, -92, -91, -91, -90, -90, -89, -89, -88, -88, -87, -86, -86, -85, -85, -84, -84, -83, -82, -82, -81, -81, -80, -79, -79, -78, -78, -77, -76, -76, -75, -74, -74, -73, -72, -72, -71, -71, -70, -69, -69, -68, -67, -67, -66, -65, -65, -64, -63, -63, -62, -61, -61, -60, -59, -58, -58, -57, -56, -56, -55, -54, -54, -53, -52, -51, -51, -50, -49, -49, -48, -47, -46, -46, -45, -44, -44, -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -35, -35, -34, -33, -32, -32, -31, -30, -29, -29, -28, -27, -26, -26, -25, -24, -23, -22, -22, -21, -20, -19, -19, -18, -17, -16, -16, -15, -14, -13, -12, -12, -11, -10, -9, -9, -8, -7, -6, -5, -5, -4, -3, -2, -2, -1, };
+
+int16_t SSTV_SIN_INT10_INT16[1024] = { 0, 201, 402, 603, 804, 1005, 1206, 1407, 1608, 1809, 2009, 2210, 2410, 2611, 2811, 3012, 3212, 3412, 3612, 3811, 4011, 4210, 4410, 4609, 4808, 5007, 5205, 5404, 5602, 5800, 5998, 6195, 6393, 6590, 6786, 6983, 7179, 7375, 7571, 7767, 7962, 8157, 8351, 8545, 8739, 8933, 9126, 9319, 9512, 9704, 9896, 10087, 10278, 10469, 10659, 10849, 11039, 11228, 11417, 11605, 11793, 11980, 12167, 12353, 12539, 12725, 12910, 13094, 13279, 13462, 13645, 13828, 14010, 14191, 14372, 14553, 14732, 14912, 15090, 15269, 15446, 15623, 15800, 15976, 16151, 16325, 16499, 16673, 16846, 17018, 17189, 17360, 17530, 17700, 17869, 18037, 18204, 18371, 18537, 18703, 18868, 19032, 19195, 19357, 19519, 19680, 19841, 20000, 20159, 20317, 20475, 20631, 20787, 20942, 21096, 21250, 21403, 21554, 21705, 21856, 22005, 22154, 22301, 22448, 22594, 22739, 22884, 23027, 23170, 23311, 23452, 23592, 23731, 23870, 24007, 24143, 24279, 24413, 24547, 24680, 24811, 24942, 25072, 25201, 25329, 25456, 25582, 25708, 25832, 25955, 26077, 26198, 26319, 26438, 26556, 26674, 26790, 26905, 27019, 27133, 27245, 27356, 27466, 27575, 27683, 27790, 27896, 28001, 28105, 28208, 28310, 28411, 28510, 28609, 28706, 28803, 28898, 28992, 29085, 29177, 29268, 29358, 29447, 29534, 29621, 29706, 29791, 29874, 29956, 30037, 30117, 30195, 30273, 30349, 30424, 30498, 30571, 30643, 30714, 30783, 30852, 30919, 30985, 31050, 31113, 31176, 31237, 31297, 31356, 31414, 31470, 31526, 31580, 31633, 31685, 31736, 31785, 31833, 31880, 31926, 31971, 32014, 32057, 32098, 32137, 32176, 32213, 32250, 32285, 32318, 32351, 32382, 32412, 32441, 32469, 32495, 32521, 32545, 32567, 32589, 32609, 32628, 32646, 32663, 32678, 32692, 32705, 32717, 32728, 32737, 32745, 32752, 32757, 32761, 32765, 32766, 32767, 32766, 32765, 32761, 32757, 32752, 32745, 32737, 32728, 32717, 32705, 32692, 32678, 32663, 32646, 32628, 32609, 32589, 32567, 32545, 32521, 32495, 32469, 32441, 32412, 32382, 32351, 32318, 32285, 32250, 32213, 32176, 32137, 32098, 32057, 32014, 31971, 31926, 31880, 31833, 31785, 31736, 31685, 31633, 31580, 31526, 31470, 31414, 31356, 31297, 31237, 31176, 31113, 31050, 30985, 30919, 30852, 30783, 30714, 30643, 30571, 30498, 30424, 30349, 30273, 30195, 30117, 30037, 29956, 29874, 29791, 29706, 29621, 29534, 29447, 29358, 29268, 29177, 29085, 28992, 28898, 28803, 28706, 28609, 28510, 28411, 28310, 28208, 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27356, 27245, 27133, 27019, 26905, 26790, 26674, 26556, 26438, 26319, 26198, 26077, 25955, 25832, 25708, 25582, 25456, 25329, 25201, 25072, 24942, 24811, 24680, 24547, 24413, 24279, 24143, 24007, 23870, 23731, 23592, 23452, 23311, 23170, 23027, 22884, 22739, 22594, 22448, 22301, 22154, 22005, 21856, 21705, 21554, 21403, 21250, 21096, 20942, 20787, 20631, 20475, 20317, 20159, 20000, 19841, 19680, 19519, 19357, 19195, 19032, 18868, 18703, 18537, 18371, 18204, 18037, 17869, 17700, 17530, 17360, 17189, 17018, 16846, 16673, 16499, 16325, 16151, 15976, 15800, 15623, 15446, 15269, 15090, 14912, 14732, 14553, 14372, 14191, 14010, 13828, 13645, 13462, 13279, 13094, 12910, 12725, 12539, 12353, 12167, 11980, 11793, 11605, 11417, 11228, 11039, 10849, 10659, 10469, 10278, 10087, 9896, 9704, 9512, 9319, 9126, 8933, 8739, 8545, 8351, 8157, 7962, 7767, 7571, 7375, 7179, 6983, 6786, 6590, 6393, 6195, 5998, 5800, 5602, 5404, 5205, 5007, 4808, 4609, 4410, 4210, 4011, 3811, 3612, 3412, 3212, 3012, 2811, 2611, 2410, 2210, 2009, 1809, 1608, 1407, 1206, 1005, 804, 603, 402, 201, 0, -201, -402, -603, -804, -1005, -1206, -1407, -1608, -1809, -2009, -2210, -2410, -2611, -2811, -3012, -3212, -3412, -3612, -3811, -4011, -4210, -4410, -4609, -4808, -5007, -5205, -5404, -5602, -5800, -5998, -6195, -6393, -6590, -6786, -6983, -7179, -7375, -7571, -7767, -7962, -8157, -8351, -8545, -8739, -8933, -9126, -9319, -9512, -9704, -9896, -10087, -10278, -10469, -10659, -10849, -11039, -11228, -11417, -11605, -11793, -11980, -12167, -12353, -12539, -12725, -12910, -13094, -13279, -13462, -13645, -13828, -14010, -14191, -14372, -14553, -14732, -14912, -15090, -15269, -15446, -15623, -15800, -15976, -16151, -16325, -16499, -16673, -16846, -17018, -17189, -17360, -17530, -17700, -17869, -18037, -18204, -18371, -18537, -18703, -18868, -19032, -19195, -19357, -19519, -19680, -19841, -20000, -20159, -20317, -20475, -20631, -20787, -20942, -21096, -21250, -21403, -21554, -21705, -21856, -22005, -22154, -22301, -22448, -22594, -22739, -22884, -23027, -23170, -23311, -23452, -23592, -23731, -23870, -24007, -24143, -24279, -24413, -24547, -24680, -24811, -24942, -25072, -25201, -25329, -25456, -25582, -25708, -25832, -25955, -26077, -26198, -26319, -26438, -26556, -26674, -26790, -26905, -27019, -27133, -27245, -27356, -27466, -27575, -27683, -27790, -27896, -28001, -28105, -28208, -28310, -28411, -28510, -28609, -28706, -28803, -28898, -28992, -29085, -29177, -29268, -29358, -29447, -29534, -29621, -29706, -29791, -29874, -29956, -30037, -30117, -30195, -30273, -30349, -30424, -30498, -30571, -30643, -30714, -30783, -30852, -30919, -30985, -31050, -31113, -31176, -31237, -31297, -31356, -31414, -31470, -31526, -31580, -31633, -31685, -31736, -31785, -31833, -31880, -31926, -31971, -32014, -32057, -32098, -32137, -32176, -32213, -32250, -32285, -32318, -32351, -32382, -32412, -32441, -32469, -32495, -32521, -32545, -32567, -32589, -32609, -32628, -32646, -32663, -32678, -32692, -32705, -32717, -32728, -32737, -32745, -32752, -32757, -32761, -32765, -32766, -32767, -32766, -32765, -32761, -32757, -32752, -32745, -32737, -32728, -32717, -32705, -32692, -32678, -32663, -32646, -32628, -32609, -32589, -32567, -32545, -32521, -32495, -32469, -32441, -32412, -32382, -32351, -32318, -32285, -32250, -32213, -32176, -32137, -32098, -32057, -32014, -31971, -31926, -31880, -31833, -31785, -31736, -31685, -31633, -31580, -31526, -31470, -31414, -31356, -31297, -31237, -31176, -31113, -31050, -30985, -30919, -30852, -30783, -30714, -30643, -30571, -30498, -30424, -30349, -30273, -30195, -30117, -30037, -29956, -29874, -29791, -29706, -29621, -29534, -29447, -29358, -29268, -29177, -29085, -28992, -28898, -28803, -28706, -28609, -28510, -28411, -28310, -28208, -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27356, -27245, -27133, -27019, -26905, -26790, -26674, -26556, -26438, -26319, -26198, -26077, -25955, -25832, -25708, -25582, -25456, -25329, -25201, -25072, -24942, -24811, -24680, -24547, -24413, -24279, -24143, -24007, -23870, -23731, -23592, -23452, -23311, -23170, -23027, -22884, -22739, -22594, -22448, -22301, -22154, -22005, -21856, -21705, -21554, -21403, -21250, -21096, -20942, -20787, -20631, -20475, -20317, -20159, -20000, -19841, -19680, -19519, -19357, -19195, -19032, -18868, -18703, -18537, -18371, -18204, -18037, -17869, -17700, -17530, -17360, -17189, -17018, -16846, -16673, -16499, -16325, -16151, -15976, -15800, -15623, -15446, -15269, -15090, -14912, -14732, -14553, -14372, -14191, -14010, -13828, -13645, -13462, -13279, -13094, -12910, -12725, -12539, -12353, -12167, -11980, -11793, -11605, -11417, -11228, -11039, -10849, -10659, -10469, -10278, -10087, -9896, -9704, -9512, -9319, -9126, -8933, -8739, -8545, -8351, -8157, -7962, -7767, -7571, -7375, -7179, -6983, -6786, -6590, -6393, -6195, -5998, -5800, -5602, -5404, -5205, -5007, -4808, -4609, -4410, -4210, -4011, -3811, -3612, -3412, -3212, -3012, -2811, -2611, -2410, -2210, -2009, -1809, -1608, -1407, -1206, -1005, -804, -603, -402, -201, };
+
diff --git a/src/luts.h b/src/luts.h
new file mode 100644
index 0000000..6332a38
--- /dev/null
+++ b/src/luts.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018 Vasile Vilvoiu (YO7JBP) <vasi.vilvoiu@gmail.com>
+ *
+ * libsstv is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#ifndef _LUTS_H_
+#define _LUTS_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern int8_t SSTV_SIN_INT10_INT8[1024];
+extern int16_t SSTV_SIN_INT10_INT16[1024];
+
+#endif \ No newline at end of file
diff --git a/src/sstv.c b/src/sstv.c
index 25fe0be..44a0cb5 100644
--- a/src/sstv.c
+++ b/src/sstv.c
@@ -165,4 +165,33 @@ sstv_delete_image(sstv_image_t *img)
/* done */
return SSTV_OK;
+}
+
+sstv_error_t
+sstv_pack_signal(sstv_signal_t *sig, sstv_sample_type_t type, size_t capacity, void *buffer)
+{
+ if (!sig) {
+ return SSTV_BAD_PARAMETER;
+ }
+
+ switch(type) {
+ case SSTV_SAMPLE_INT8:
+ sig->size = capacity;
+ break;
+
+ case SSTV_SAMPLE_INT16:
+ sig->size = 2 * capacity;
+ break;
+
+ default:
+ return SSTV_BAD_SAMPLE_TYPE;
+ }
+
+ sig->buffer = buffer;
+ sig->type = type;
+ sig->capacity = capacity;
+ sig->count = 0;
+
+ /* done */
+ return SSTV_OK;
} \ No newline at end of file
diff --git a/src/tools/sstv-encode.cpp b/src/tools/sstv-encode.cpp
index 9c7c141..4daf370 100644
--- a/src/tools/sstv-encode.cpp
+++ b/src/tools/sstv-encode.cpp
@@ -54,6 +54,13 @@ int main(int argc, char **argv)
LOG(FATAL) << "sstv_pack_image() failed";
}
+ /* create a sample buffer for output */
+ int8_t samp_buffer[128 * 1024];
+ sstv_signal_t signal;
+ if (sstv_pack_signal(&signal, SSTV_SAMPLE_INT8, 128 * 1024, samp_buffer) != SSTV_OK) {
+ LOG(FATAL) << "sstv_pack_signal() failed";
+ }
+
/* initialize library */
LOG(INFO) << "Initializing libsstv";
if (sstv_init(malloc, free) != SSTV_OK) {
@@ -70,6 +77,26 @@ int main(int argc, char **argv)
LOG(FATAL) << "NULL encoder received";
}
+ /* encode */
+ while (true) {
+ /* encode block */
+ sstv_error_t rc = sstv_encode(ctx, &signal);
+ if (rc != SSTV_ENCODE_SUCCESSFUL && rc != SSTV_ENCODE_END) {
+ LOG(FATAL) << "sstv_encode() failed with rc " << rc;
+ }
+
+ /* DEBUG: print block as csv */
+ for (size_t i=0; i < signal.count; i ++) {
+ std::cout << (int)((int8_t *)signal.buffer)[i] << std::endl;
+ }
+ std::cout << std::endl << std::endl;
+
+ /* exit case */
+ if (rc == SSTV_ENCODE_END) {
+ break;
+ }
+ }
+
/* cleanup */
LOG(INFO) << "Cleaning up";
if (sstv_delete_encoder(ctx) != SSTV_OK) {
diff --git a/util/genluts.py b/util/genluts.py
new file mode 100644
index 0000000..fcaead9
--- /dev/null
+++ b/util/genluts.py
@@ -0,0 +1,30 @@
+import sys
+import numpy as np
+
+f = open('src/luts.c', 'w')
+
+# header
+f.write('/*\n')
+f.write(' * Copyright (c) 2018 Vasile Vilvoiu (YO7JBP) <vasi.vilvoiu@gmail.com>\n')
+f.write(' *\n')
+f.write(' * libsstv is free software; you can redistribute it and/or modify\n')
+f.write(' * it under the terms of the MIT license. See LICENSE for details.\n')
+f.write(' */\n\n')
+f.write('#include "luts.h"\n\n')
+
+x = np.linspace(0.0, 2 * np.pi, num=1024, endpoint=False)
+sn = np.sin(x)
+
+# SSTV_SIN_INT10_INT8
+f.write('int8_t SSTV_SIN_INT10_INT8[1024] = { ')
+for s in sn * 127:
+ f.write(str(int(np.around(s))) + ', ')
+f.write('};\n\n')
+
+# SSTV_SIN_INT10_INT16
+f.write('int16_t SSTV_SIN_INT10_INT16[1024] = { ')
+for s in sn * 32767:
+ f.write(str(int(np.around(s))) + ', ')
+f.write('};\n\n')
+
+f.close() \ No newline at end of file
diff --git a/util/view.py b/util/view.py
new file mode 100644
index 0000000..b6e95fe
--- /dev/null
+++ b/util/view.py
@@ -0,0 +1,11 @@
+import sys
+import numpy as np
+import matplotlib.pyplot as plt
+
+f = open('test.csv')
+lines = [int(l.replace('\n', '')) for l in f.readlines()[:-2]]
+f.close()
+
+s = np.array(lines)
+plt.plot(s)
+plt.show()