* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <stdint.h>
-#include "libsigrok.h"
+#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
#define LOG_PREFIX "input/wav"
#define MIN_DATA_CHUNK_OFFSET 45
/* Expect to find the "data" chunk within this offset from the start. */
-#define MAX_DATA_CHUNK_OFFSET 256
+#define MAX_DATA_CHUNK_OFFSET 1024
-#define WAVE_FORMAT_PCM 0x0001
-#define WAVE_FORMAT_IEEE_FLOAT 0x0003
-#define WAVE_FORMAT_EXTENSIBLE 0xfffe
+#define WAVE_FORMAT_PCM_ 0x0001
+#define WAVE_FORMAT_IEEE_FLOAT_ 0x0003
+#define WAVE_FORMAT_EXTENSIBLE_ 0xfffe
struct context {
gboolean started;
return SR_ERR_DATA;
}
-
- if (fmt_code == WAVE_FORMAT_PCM) {
- } else if (fmt_code == WAVE_FORMAT_IEEE_FLOAT) {
+ if (fmt_code == WAVE_FORMAT_PCM_) {
+ } else if (fmt_code == WAVE_FORMAT_IEEE_FLOAT_) {
if (unitsize != 4) {
sr_err("only 32-bit floats supported.");
return SR_ERR_DATA;
}
- } else if (fmt_code == WAVE_FORMAT_EXTENSIBLE) {
+ } else if (fmt_code == WAVE_FORMAT_EXTENSIBLE_) {
if (buf->len < 70)
/* Not enough for extensible header and next chunk. */
return SR_ERR_NA;
}
/* Real format code is the first two bytes of the GUID. */
fmt_code = RL16(buf->str + 44);
- if (fmt_code != WAVE_FORMAT_PCM && fmt_code != WAVE_FORMAT_IEEE_FLOAT) {
+ if (fmt_code != WAVE_FORMAT_PCM_ && fmt_code != WAVE_FORMAT_IEEE_FLOAT_) {
sr_err("Only PCM and floating point samples are supported.");
return SR_ERR_DATA;
}
- if (fmt_code == WAVE_FORMAT_IEEE_FLOAT && unitsize != 4) {
+ if (fmt_code == WAVE_FORMAT_IEEE_FLOAT_ && unitsize != 4) {
sr_err("only 32-bit floats supported.");
return SR_ERR_DATA;
}
unsigned int offset, i;
offset = initial_offset;
- while(offset < MIN(MAX_DATA_CHUNK_OFFSET, buf->len)) {
+ while (offset < MIN(MAX_DATA_CHUNK_OFFSET, buf->len)) {
if (!memcmp(buf->str + offset, "data", 4))
/* Skip into the samples. */
return offset + 8;
for (i = 0; i < 4; i++) {
- if (!isalpha(buf->str[offset + i])
- && !isascii(buf->str[offset + i])
+ if (!isalnum(buf->str[offset + i])
&& !isblank(buf->str[offset + i]))
/* Doesn't look like a chunk ID. */
return -1;
offset += 8 + RL32(buf->str + offset + 4);
}
+ if (offset > MAX_DATA_CHUNK_OFFSET)
+ return -1;
+
return offset;
}
static void send_chunk(const struct sr_input *in, int offset, int num_samples)
{
struct sr_datafeed_packet packet;
- struct sr_datafeed_analog analog;
+ struct sr_datafeed_analog_old analog;
struct context *inc;
float fdata[CHUNK_SIZE];
- uint64_t sample;
int total_samples, samplenum;
char *s, *d;
memset(fdata, 0, CHUNK_SIZE);
total_samples = num_samples * inc->num_channels;
for (samplenum = 0; samplenum < total_samples; samplenum++) {
- if (inc->fmt_code == WAVE_FORMAT_PCM) {
- sample = 0;
- memcpy(&sample, s, inc->unitsize);
- switch (inc->samplesize) {
+ if (inc->fmt_code == WAVE_FORMAT_PCM_) {
+ switch (inc->unitsize) {
case 1:
/* 8-bit PCM samples are unsigned. */
- fdata[samplenum] = (uint8_t)sample / (float)255;
+ fdata[samplenum] = *(uint8_t*)(s) / (float)255;
break;
case 2:
- fdata[samplenum] = RL16S(&sample) / (float)INT16_MAX;
+ fdata[samplenum] = RL16S(s) / (float)INT16_MAX;
break;
case 4:
- fdata[samplenum] = RL32S(&sample) / (float)INT32_MAX;
+ fdata[samplenum] = RL32S(s) / (float)INT32_MAX;
break;
}
} else {
s += inc->unitsize;
d += inc->unitsize;
}
- packet.type = SR_DF_ANALOG;
+ packet.type = SR_DF_ANALOG_OLD;
packet.payload = &analog;
analog.channels = in->sdi->channels;
analog.num_samples = num_samples;
src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(inc->samplerate));
meta.config = g_slist_append(NULL, src);
sr_session_send(in->sdi, &packet);
+ g_slist_free(meta.config);
sr_config_free(src);
inc->started = TRUE;
offset = 0;
/* Round off up to the last channels * unitsize boundary. */
- chunk_samples = (in->buf->len - offset) / inc->num_channels / inc->unitsize;
- max_chunk_samples = CHUNK_SIZE / inc->num_channels / inc->unitsize;
+ chunk_samples = (in->buf->len - offset) / inc->samplesize;
+ max_chunk_samples = CHUNK_SIZE / inc->samplesize;
processed = 0;
total_samples = chunk_samples;
while (processed < total_samples) {
else
num_samples = chunk_samples;
send_chunk(in, offset, num_samples);
- offset += num_samples * inc->unitsize;
+ offset += num_samples * inc->samplesize;
chunk_samples -= num_samples;
processed += num_samples;
}
.receive = receive,
.end = end,
};
-