From e8eb24222c862fd8fd8a6690c65305e864b47882 Mon Sep 17 00:00:00 2001 From: Gerhard Sittig Date: Sun, 13 May 2018 12:28:07 +0200 Subject: [PATCH] input/chronovu_la8: only send data to the session, don't send the header The file format is funny, a data part is leading (fixed size) and a "header" part follows. The previous implementation sent the header part to the session, too, pretending it was part of the data. This change limits the number of samples that get sent to the session. Comment on the file layout and header fields while we are here. This information got lost in commit 02e24c0ce0d8 when the input module got converted from do-it-yourself file operations to having intrinsic handler routines invoked from common logic which handles the file. --- src/input/chronovu_la8.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/input/chronovu_la8.c b/src/input/chronovu_la8.c index e83d5822..11fc36a6 100644 --- a/src/input/chronovu_la8.c +++ b/src/input/chronovu_la8.c @@ -30,11 +30,27 @@ #define DEFAULT_NUM_CHANNELS 8 #define DEFAULT_SAMPLERATE SR_MHZ(100) #define CHUNK_SIZE (4 * 1024 * 1024) -#define CHRONOVU_LA8_FILESIZE ((8 * 1024 * 1024) + 5) + +/* + * File layout: + * - Fixed size 8MiB data part at offset 0. + * - Either one byte per sample for LA8. + * - Or two bytes per sample for LA16, in little endian format. + * - Five byte "header" at offset 8MiB. + * - One "clock divider" byte. The byte value is the divider factor + * minus 1. Value 0xff is invalid. Base clock is 100MHz for LA8, or + * 200MHz for LA16. + * - Four bytes for the trigger position. This 32bit value is the + * sample number in little endian format, or 0 when unused. + */ +#define CHRONOVU_LA8_DATASIZE (8 * 1024 * 1024) +#define CHRONOVU_LA8_HDRSIZE (sizeof(uint8_t) + sizeof(uint32_t)) +#define CHRONOVU_LA8_FILESIZE (CHRONOVU_LA8_DATASIZE + CHRONOVU_LA8_HDRSIZE) struct context { gboolean started; uint64_t samplerate; + uint64_t samples_remain; }; static int format_match(GHashTable *metadata, unsigned int *confidence) @@ -89,9 +105,12 @@ static int process_buffer(struct sr_input *in) struct sr_config *src; struct context *inc; gsize chunk_size, i; - int chunk; + gsize chunk; + uint16_t unitsize; inc = in->priv; + unitsize = (g_slist_length(in->sdi->channels) + 7) / 8; + if (!inc->started) { std_session_send_df_header(in->sdi); @@ -105,21 +124,28 @@ static int process_buffer(struct sr_input *in) sr_config_free(src); } + inc->samples_remain = CHRONOVU_LA8_DATASIZE; + inc->samples_remain /= unitsize; + inc->started = TRUE; } packet.type = SR_DF_LOGIC; packet.payload = &logic; - logic.unitsize = (g_slist_length(in->sdi->channels) + 7) / 8; + logic.unitsize = unitsize; - /* Cut off at multiple of unitsize. */ + /* Cut off at multiple of unitsize. Avoid sending the "header". */ chunk_size = in->buf->len / logic.unitsize * logic.unitsize; + chunk_size = MIN(chunk_size, inc->samples_remain * unitsize); for (i = 0; i < chunk_size; i += chunk) { logic.data = in->buf->str + i; chunk = MIN(CHUNK_SIZE, chunk_size - i); - logic.length = chunk; - sr_session_send(in->sdi, &packet); + if (chunk) { + logic.length = chunk; + sr_session_send(in->sdi, &packet); + inc->samples_remain -= chunk / unitsize; + } } g_string_erase(in->buf, 0, chunk_size);