X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Foutput%2Fwav.c;h=507e0e77b53700ad2e9ac71cac01b3730a008e34;hb=d09a82a8fe04f9554f99c5141dd9eb7552612156;hp=61d184ccb5ce52333ce266605b7588022287f22c;hpb=7ea75009d1977874efb686b000516c4ce1343474;p=libsigrok.git diff --git a/src/output/wav.c b/src/output/wav.c index 61d184cc..507e0e77 100644 --- a/src/output/wav.c +++ b/src/output/wav.c @@ -17,8 +17,9 @@ * along with this program. If not, see . */ +#include #include -#include "libsigrok.h" +#include #include "libsigrok-internal.h" #define LOG_PREFIX "output/wav" @@ -91,28 +92,10 @@ static int init(struct sr_output *o, GHashTable *options) struct out_context *outc; struct sr_channel *ch; GSList *l; - 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; - } - } - } + outc->scale = g_variant_get_double(g_hash_table_lookup(options, "scale")); for (l = o->sdi->channels; l; l = l->next) { ch = l->data; @@ -247,17 +230,21 @@ 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) { struct out_context *outc; const struct sr_datafeed_meta *meta; + const struct sr_datafeed_analog_old *analog_old; const struct sr_datafeed_analog *analog; const struct sr_config *src; struct sr_channel *ch; GSList *l; + const GSList *channels; float f; - int num_channels, size, *chan_idx, idx, i, j; + int num_channels, num_samples, size, *chan_idx, idx, i, j, ret; + float *data; uint8_t *buf; *out = NULL; @@ -274,6 +261,7 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p outc->samplerate = g_variant_get_uint64(src->data); } break; + case SR_DF_ANALOG_OLD: case SR_DF_ANALOG: if (!outc->header_done) { *out = gen_header(o); @@ -281,34 +269,50 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p } else *out = g_string_sized_new(512); + analog_old = packet->payload; analog = packet->payload; - if (analog->num_samples == 0) + + if (packet->type == SR_DF_ANALOG_OLD) { + num_samples = analog_old->num_samples; + channels = analog_old->channels; + num_channels = g_slist_length(analog_old->channels); + data = analog_old->data; + } else { + num_samples = analog->num_samples; + channels = analog->meaning->channels; + num_channels = g_slist_length(analog->meaning->channels); + data = g_malloc(sizeof(float) * num_samples * num_channels); + ret = sr_analog_to_float(analog, data); + if (ret != SR_OK) + return ret; + } + + if (num_samples == 0) return SR_OK; - num_channels = g_slist_length(analog->channels); if (num_channels > outc->num_channels) { sr_err("Packet has %d channels, but only %d were enabled.", num_channels, outc->num_channels); return SR_ERR; } - if (analog->num_samples > outc->chanbuf_size) { - if (realloc_chanbufs(o, analog->num_samples) != SR_OK) + if (num_samples > outc->chanbuf_size) { + if (realloc_chanbufs(o, analog_old->num_samples) != SR_OK) return SR_ERR_MALLOC; } /* Index the channels in this packet, so we can interleave quicker. */ chan_idx = g_malloc(sizeof(int) * outc->num_channels); for (i = 0; i < num_channels; i++) { - ch = g_slist_nth_data(analog->channels, i); + ch = g_slist_nth_data((GSList *) channels, i); chan_idx[i] = g_slist_index(outc->channels, ch); } - for (i = 0; i < analog->num_samples; i++) { + for (i = 0; i < num_samples; i++) { for (j = 0; j < num_channels; j++) { idx = chan_idx[j]; buf = outc->chanbuf[idx] + outc->chanbuf_used[idx]++ * 4; - f = analog->data[i * num_channels + j]; + f = analog_old->data[i * num_channels + j]; if (outc->scale != 0.0) f /= outc->scale; float_to_le(buf, f); @@ -353,16 +357,13 @@ static int cleanup(struct sr_output *o) static struct sr_option options[] = { { "scale", "Scale", "Scale values by factor", NULL, NULL }, - { 0 } + ALL_ZERO }; -static struct sr_option *get_options(gboolean cached) +static const struct sr_option *get_options(void) { - if (cached) - return options; - - options[0].def = g_variant_new_double(0); - g_variant_ref_sink(options[0].def); + if (!options[0].def) + options[0].def = g_variant_ref_sink(g_variant_new_double(0.0)); return options; } @@ -370,10 +371,11 @@ static struct sr_option *get_options(gboolean cached) 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}, + .flags = 0, .options = get_options, .init = init, .receive = receive, .cleanup = cleanup, }; -