diff --git a/hardware/alsa/api.c b/hardware/alsa/api.c index dc762e06..a8806fc2 100644 --- a/hardware/alsa/api.c +++ b/hardware/alsa/api.c @@ -209,9 +209,11 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, struct sr_datafeed_meta_analog meta; struct dev_context *devc; int count, ret; + char *endianess; devc = sdi->priv; devc->cb_data = cb_data; + devc->num_samples = 0; sr_dbg("Setting audio access type to RW/interleaved."); ret = snd_pcm_hw_params_set_access(devc->capture_handle, @@ -222,9 +224,14 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, } /* FIXME: Hardcoded for 16bits. */ - sr_dbg("Setting audio sample format to signed 16bit (little endian)."); + if (SND_PCM_FORMAT_S16 == SND_PCM_FORMAT_S16_LE) + endianess = "lilltle endian"; + else + endianess = "big endian"; + sr_dbg("Setting audio sample format to signed 16bit (%s).", endianess); ret = snd_pcm_hw_params_set_format(devc->capture_handle, - devc->hw_params, SND_PCM_FORMAT_S16_LE); + devc->hw_params, + SND_PCM_FORMAT_S16); if (ret < 0) { sr_err("Can't set audio sample format: %s.", snd_strerror(ret)); return SR_ERR; diff --git a/hardware/alsa/protocol.c b/hardware/alsa/protocol.c index 1c1d8849..a501ec8f 100644 --- a/hardware/alsa/protocol.c +++ b/hardware/alsa/protocol.c @@ -230,9 +230,10 @@ SR_PRIV int alsa_receive_data(int fd, int revents, void *cb_data) struct dev_context *devc; struct sr_datafeed_packet packet; struct sr_datafeed_analog analog; - char inbuf[4096]; + int16_t inbuf[4096]; int i, x, count, offset, samples_to_get; - uint16_t tmp16; + int16_t tmp16; + const float s16norm = 1 / (float)(1<<15); (void)fd; (void)revents; @@ -262,11 +263,18 @@ SR_PRIV int alsa_receive_data(int fd, int revents, void *cb_data) } offset = 0; - - for (i = 0; i < count; i++) { + /* + * It's impossible to know what voltage levels the soundcard handles. + * Some handle 0 dBV rms, some 0dBV peak-to-peak, +4dbmW (600 ohm), etc + * Each of these corresponds to a different voltage, and there is no + * mechanism to determine this voltage. The best solution is to send all + * audio data as a normalized float, and let the frontend or user worry + * about the calibration. + */ + for (i = 0; i < count; i += devc->num_probes) { for (x = 0; x < devc->num_probes; x++) { - tmp16 = *(uint16_t *)(inbuf + (i * 4) + (x * 2)); - analog.data[offset++] = (float)tmp16; + tmp16 = inbuf[i+x]; + analog.data[offset++] = tmp16 * s16norm; } }