From: Bert Vermeulen Date: Sat, 2 Aug 2014 01:48:55 +0000 (+0200) Subject: output/wav: Add 'scale' option. X-Git-Tag: libsigrok-0.4.0~1176 X-Git-Url: https://sigrok.org/gitweb/?a=commitdiff_plain;h=7ea75009d1977874efb686b000516c4ce1343474;p=libsigrok.git output/wav: Add 'scale' option. Audio tools processing WAV failes generally need the samples to be in the range -1 to +1. The scale option adds postprocessing to any samples going into a WAV file, by dividing the sample values by the given factor. --- diff --git a/src/output/wav.c b/src/output/wav.c index 8aa787bd..61d184cc 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; @@ -90,12 +91,29 @@ static int init(struct sr_output *o, GHashTable *options) struct out_context *outc; struct sr_channel *ch; GSList *l; - - (void)options; + GHashTableIter iter; + gpointer key, value; outc = g_malloc0(sizeof(struct out_context)); o->priv = outc; + outc->scale = 0.0; + if (options) { + g_hash_table_iter_init(&iter, options); + while (g_hash_table_iter_next(&iter, &key, &value)) { + if (!strcmp(key, "scale")) { + if (!g_variant_is_of_type(value, G_VARIANT_TYPE_DOUBLE)) { + sr_err("Invalid type for 'scale' option."); + return SR_ERR_ARG; + } + outc->scale = g_variant_get_double(value); + } else { + sr_err("Unknown option '%s'.", key); + return SR_ERR_ARG; + } + } + } + for (l = o->sdi->channels; l; l = l->next) { ch = l->data; if (ch->type != SR_CHANNEL_ANALOG) @@ -238,6 +256,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; @@ -289,7 +308,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 * num_channels + 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); @@ -329,10 +351,27 @@ static int cleanup(struct sr_output *o) return SR_OK; } +static struct sr_option options[] = { + { "scale", "Scale", "Scale values by factor", NULL, NULL }, + { 0 } +}; + +static struct sr_option *get_options(gboolean cached) +{ + if (cached) + return options; + + options[0].def = g_variant_new_double(0); + g_variant_ref_sink(options[0].def); + + return options; +} + SR_PRIV struct sr_output_module output_wav = { .id = "wav", .name = "WAV", .desc = "WAVE file format", + .options = get_options, .init = init, .receive = receive, .cleanup = cleanup,