X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Foutput%2Fwav.c;h=45854caac1f684f445d2bee87e032e9cff831c79;hb=a82c83c6a506a41154344593948de859e5b9ae7e;hp=e6688ed08a8619bd941d9bfcc80bae098b98899c;hpb=0605f874754be5b6c8eb8b8bca481c0d47ea3f48;p=libsigrok.git diff --git a/src/output/wav.c b/src/output/wav.c index e6688ed0..45854caa 100644 --- a/src/output/wav.c +++ b/src/output/wav.c @@ -27,6 +27,7 @@ #define MIN_DATA_CHUNK_SAMPLES 10 struct out_context { + double scale; gboolean header_done; uint64_t samplerate; int num_channels; @@ -57,29 +58,26 @@ static int realloc_chanbufs(const struct sr_output *o, int size) static int flush_chanbufs(const struct sr_output *o, GString *out) { struct out_context *outc; - int size, i, j; - char *buf, **bufp; + int num_samples, i, j; + char *buf, *bufp; outc = o->priv; /* Any one of them will do. */ - size = outc->chanbuf_used[0]; - if (!(buf = g_try_malloc(4 * size * outc->num_channels))) { + num_samples = outc->chanbuf_used[0]; + if (!(buf = g_try_malloc(4 * num_samples * outc->num_channels))) { sr_err("Unable to allocate enough interleaved output buffer memory."); return SR_ERR; } - bufp = g_malloc(sizeof(char *) * outc->num_channels); - for (i = 0; i < outc->num_channels; i++) - bufp[i] = buf + i * 4; - for (i = 0; i < size * 4; i += 4) { + bufp = buf; + for (i = 0; i < num_samples; i++) { for (j = 0; j < outc->num_channels; j++) { - memcpy(bufp[j], outc->chanbuf[j] + i, 4); - bufp[j] += outc->num_channels * 4; + memcpy(bufp, outc->chanbuf[j] + i * 4, 4); + bufp += 4; } } - g_string_append_len(out, buf, 4 * size * outc->num_channels); - g_free(bufp); + g_string_append_len(out, buf, 4 * num_samples * outc->num_channels); g_free(buf); for (i = 0; i < outc->num_channels; i++) @@ -94,10 +92,9 @@ static int init(struct sr_output *o, GHashTable *options) struct sr_channel *ch; GSList *l; - (void)options; - outc = g_malloc0(sizeof(struct out_context)); o->priv = outc; + outc->scale = g_variant_get_double(g_hash_table_lookup(options, "scale")); for (l = o->sdi->channels; l; l = l->next) { ch = l->data; @@ -232,6 +229,7 @@ static int check_chanbuf_size(const struct sr_output *o) return size; } + static int receive(const struct sr_output *o, const struct sr_datafeed_packet *packet, GString **out) { @@ -241,6 +239,7 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p const struct sr_config *src; struct sr_channel *ch; GSList *l; + float f; int num_channels, size, *chan_idx, idx, i, j; uint8_t *buf; @@ -292,7 +291,10 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p for (j = 0; j < num_channels; j++) { idx = chan_idx[j]; buf = outc->chanbuf[idx] + outc->chanbuf_used[idx]++ * 4; - float_to_le(buf, analog->data[i + j]); + f = analog->data[i * num_channels + j]; + if (outc->scale != 0.0) + f /= outc->scale; + float_to_le(buf, f); } } g_free(chan_idx); @@ -332,10 +334,25 @@ static int cleanup(struct sr_output *o) return SR_OK; } +static struct sr_option options[] = { + { "scale", "Scale", "Scale values by factor", NULL, NULL }, + ALL_ZERO +}; + +static const struct sr_option *get_options(void) +{ + if (!options[0].def) + options[0].def = g_variant_ref_sink(g_variant_new_double(0.0)); + + return options; +} + SR_PRIV struct sr_output_module output_wav = { .id = "wav", .name = "WAV", - .desc = "WAVE file format", + .desc = "Microsoft WAV file format", + .exts = (const char*[]){"wav", NULL}, + .options = get_options, .init = init, .receive = receive, .cleanup = cleanup,