+++ /dev/null
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2011 Daniel Ribeiro <drwyrm@gmail.com>
- * Copyright (C) 2012 Uwe Hermann <uwe@hermann-uwe.de>
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include "libsigrok.h"
-#include "libsigrok-internal.h"
-#include "protocol.h"
-
-static const int32_t hwcaps[] = {
- SR_CONF_SAMPLERATE,
- SR_CONF_LIMIT_SAMPLES,
- SR_CONF_CONTINUOUS,
-};
-
-SR_PRIV struct sr_dev_driver alsa_driver_info;
-static struct sr_dev_driver *di = &alsa_driver_info;
-
-static void clear_helper(void *priv)
-{
- struct dev_context *devc;
-
- devc = priv;
-
- snd_pcm_hw_params_free(devc->hw_params);
- devc->hw_params = NULL;
-
- g_free((void *)devc->samplerates);
- devc->samplerates = NULL;
-}
-
-static int dev_clear(void)
-{
- return std_dev_clear(di, clear_helper);
-}
-
-static int init(struct sr_context *sr_ctx)
-{
- return std_init(sr_ctx, di, LOG_PREFIX);
-}
-
-static GSList *scan(GSList *options)
-{
- return alsa_scan(options, di);
-}
-
-static GSList *dev_list(void)
-{
- return ((struct drv_context *)(di->priv))->instances;
-}
-
-static int dev_open(struct sr_dev_inst *sdi)
-{
- struct dev_context *devc;
- int ret;
-
- devc = sdi->priv;
-
- if (!(devc->hwdev)) {
- sr_err("devc->hwdev was NULL.");
- return SR_ERR_BUG;
- }
-
- sr_dbg("Opening audio device '%s' for stream capture.", devc->hwdev);
- ret = snd_pcm_open(&devc->capture_handle, devc->hwdev,
- SND_PCM_STREAM_CAPTURE, 0);
- if (ret < 0) {
- sr_err("Can't open audio device: %s.", snd_strerror(ret));
- return SR_ERR;
- }
-
- sr_dbg("Initializing hardware parameter structure.");
- ret = snd_pcm_hw_params_any(devc->capture_handle, devc->hw_params);
- if (ret < 0) {
- sr_err("Can't initialize hardware parameter structure: %s.",
- snd_strerror(ret));
- return SR_ERR;
- }
-
- sdi->status = SR_ST_ACTIVE;
-
- return SR_OK;
-}
-
-static int dev_close(struct sr_dev_inst *sdi)
-{
- int ret;
- struct dev_context *devc;
-
- devc = sdi->priv;
-
- if (devc->capture_handle) {
- sr_dbg("Closing PCM device.");
- if ((ret = snd_pcm_close(devc->capture_handle)) < 0)
- sr_err("Failed to close device: %s.",
- snd_strerror(ret));
- devc->capture_handle = NULL;
- sdi->status = SR_ST_INACTIVE;
- } else {
- sr_dbg("No capture handle, no need to close audio device.");
- }
-
- return SR_OK;
-}
-
-static int cleanup(void)
-{
- return dev_clear();
-}
-
-static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
- const struct sr_channel_group *cg)
-{
- struct dev_context *devc;
-
- (void)cg;
-
- switch (id) {
- case SR_CONF_SAMPLERATE:
- devc = sdi->priv;
- *data = g_variant_new_uint64(devc->cur_samplerate);
- break;
- default:
- return SR_ERR_NA;
- }
-
- return SR_OK;
-}
-
-static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
- const struct sr_channel_group *cg)
-{
- struct dev_context *devc;
-
- (void)cg;
-
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR_DEV_CLOSED;
-
- devc = sdi->priv;
-
- switch (id) {
- case SR_CONF_SAMPLERATE:
- alsa_set_samplerate(sdi, g_variant_get_uint64(data));
- break;
- case SR_CONF_LIMIT_SAMPLES:
- devc->limit_samples = g_variant_get_uint64(data);
- break;
- default:
- return SR_ERR_NA;
- }
-
- return SR_OK;
-}
-
-static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
- const struct sr_channel_group *cg)
-{
- struct dev_context *devc;
- GVariant *gvar;
- GVariantBuilder gvb;
- int i;
-
- (void)cg;
-
- switch (key) {
- case SR_CONF_DEVICE_OPTIONS:
- *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
- hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
- break;
- case SR_CONF_SAMPLERATE:
- if (!sdi || !sdi->priv)
- return SR_ERR_ARG;
- devc = sdi->priv;
- if (!devc->samplerates) {
- sr_err("Instance did not contain a samplerate list.");
- return SR_ERR_ARG;
- }
- for (i = 0; devc->samplerates[i]; i++)
- ;
- g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
- gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
- devc->samplerates, i, sizeof(uint64_t));
- g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
- *data = g_variant_builder_end(&gvb);
- break;
- default:
- return SR_ERR_NA;
- }
-
- return SR_OK;
-}
-
-static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
-{
- struct dev_context *devc;
- int count, ret;
- char *endianness;
-
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR_DEV_CLOSED;
-
- 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,
- devc->hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
- if (ret < 0) {
- sr_err("Can't set audio access type: %s.", snd_strerror(ret));
- return SR_ERR;
- }
-
- /* FIXME: Hardcoded for 16bits. */
- if (SND_PCM_FORMAT_S16 == SND_PCM_FORMAT_S16_LE)
- endianness = "little endian";
- else
- endianness = "big endian";
- sr_dbg("Setting audio sample format to signed 16bit (%s).", endianness);
- ret = snd_pcm_hw_params_set_format(devc->capture_handle,
- 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;
- }
-
- sr_dbg("Setting audio samplerate to %" PRIu64 "Hz.",
- devc->cur_samplerate);
- ret = snd_pcm_hw_params_set_rate(devc->capture_handle, devc->hw_params,
- (unsigned int)devc->cur_samplerate, 0);
- if (ret < 0) {
- sr_err("Can't set audio sample rate: %s.", snd_strerror(ret));
- return SR_ERR;
- }
-
- sr_dbg("Setting audio channel count to %d.", devc->num_channels);
- ret = snd_pcm_hw_params_set_channels(devc->capture_handle,
- devc->hw_params, devc->num_channels);
- if (ret < 0) {
- sr_err("Can't set channel count: %s.", snd_strerror(ret));
- return SR_ERR;
- }
-
- sr_dbg("Setting audio parameters.");
- ret = snd_pcm_hw_params(devc->capture_handle, devc->hw_params);
- if (ret < 0) {
- sr_err("Can't set parameters: %s.", snd_strerror(ret));
- return SR_ERR;
- }
-
- sr_dbg("Preparing audio interface for use.");
- ret = snd_pcm_prepare(devc->capture_handle);
- if (ret < 0) {
- sr_err("Can't prepare audio interface for use: %s.",
- snd_strerror(ret));
- return SR_ERR;
- }
-
- count = snd_pcm_poll_descriptors_count(devc->capture_handle);
- if (count < 1) {
- sr_err("Unable to obtain poll descriptors count.");
- return SR_ERR;
- }
-
- if (!(devc->ufds = g_try_malloc(count * sizeof(struct pollfd)))) {
- sr_err("Failed to malloc ufds.");
- return SR_ERR_MALLOC;
- }
-
- sr_spew("Getting %d poll descriptors.", count);
- ret = snd_pcm_poll_descriptors(devc->capture_handle, devc->ufds, count);
- if (ret < 0) {
- sr_err("Unable to obtain poll descriptors: %s.",
- snd_strerror(ret));
- g_free(devc->ufds);
- return SR_ERR;
- }
-
- /* Send header packet to the session bus. */
- std_session_send_df_header(cb_data, LOG_PREFIX);
-
- /* Poll every 10ms, or whenever some data comes in. */
- sr_source_add(devc->ufds[0].fd, devc->ufds[0].events, 10,
- alsa_receive_data, (void *)sdi);
-
- // g_free(devc->ufds); /* FIXME */
-
- return SR_OK;
-}
-
-static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
-{
- struct sr_datafeed_packet packet;
- struct dev_context *devc;
-
- devc = sdi->priv;
- devc->cb_data = cb_data;
-
- sr_source_remove(devc->ufds[0].fd);
-
- /* Send end packet to the session bus. */
- sr_dbg("Sending SR_DF_END packet.");
- packet.type = SR_DF_END;
- sr_session_send(cb_data, &packet);
-
- return SR_OK;
-}
-
-SR_PRIV struct sr_dev_driver alsa_driver_info = {
- .name = "alsa",
- .longname = "ALSA driver",
- .api_version = 1,
- .init = init,
- .cleanup = cleanup,
- .scan = scan,
- .dev_list = dev_list,
- .dev_clear = dev_clear,
- .config_get = config_get,
- .config_set = config_set,
- .config_list = config_list,
- .dev_open = dev_open,
- .dev_close = dev_close,
- .dev_acquisition_start = dev_acquisition_start,
- .dev_acquisition_stop = dev_acquisition_stop,
- .priv = NULL,
-};
+++ /dev/null
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2011 Daniel Ribeiro <drwyrm@gmail.com>
- * Copyright (C) 2012 Uwe Hermann <uwe@hermann-uwe.de>
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libsigrok.h"
-#include "libsigrok-internal.h"
-#include "protocol.h"
-
-/*
- * There is no way to get a list of supported samplerates from ALSA. We could
- * use the 'plughw' interface of ALSA, in which case any format and/or
- * samplerate conversion would be performed by ALSA. However, we are interested
- * in the hardware capabilities, and have the infrastructure in sigrok to do so.
- * We therefore use the 'hw' interface. The downside is that the code gets a
- * little bulkier, as we have to keep track of the hardware capabilities, and
- * only use those that the hardware supports. Case in point, ALSA will not give
- * us a list of capabilities; we have to test for each one individually. Hence,
- * we keep lists of the capabilities we are interested in.
- */
-static const unsigned int rates[] = {
- 5512,
- 8000,
- 11025,
- 12000,
- 16000,
- 22050,
- 24000,
- 32000,
- 44100,
- 48000,
- 64000,
- 88200,
- 96000,
- 176400,
- 192000,
- 384000,
- 768000, /* Yes, there are sound cards that go this high. */
-};
-
-static void alsa_scan_handle_dev(GSList **devices,
- const char *cardname, const char *alsaname,
- struct sr_dev_driver *di,
- snd_pcm_info_t *pcminfo)
-{
- struct drv_context *drvc = NULL;
- struct sr_dev_inst *sdi = NULL;
- struct dev_context *devc = NULL;
- struct sr_channel *ch;
- int ret;
- unsigned int i, offset, channels, minrate, maxrate, rate;
- uint64_t hwrates[ARRAY_SIZE(rates)];
- uint64_t *devrates = NULL;
- snd_pcm_t *temp_handle = NULL;
- snd_pcm_hw_params_t *hw_params = NULL;
- char p_name[32];
-
- drvc = di->priv;
-
- /*
- * Get hardware parameters:
- * The number of channels, for example, are our sigrok channels. Getting
- * this information needs a detour. We need to open the device, then
- * query it and/or test different parameters. A side-effect of is that
- * we create a snd_pcm_hw_params_t object. We take advantage of the
- * situation, and pass this object in our dev_context->hw_params,
- * eliminating the need to free() it and malloc() it later.
- */
- ret = snd_pcm_open(&temp_handle, alsaname, SND_PCM_STREAM_CAPTURE, 0);
- if (ret < 0) {
- sr_err("Cannot open device: %s.", snd_strerror(ret));
- goto scan_error_cleanup;
- }
-
- ret = snd_pcm_hw_params_malloc(&hw_params);
- if (ret < 0) {
- sr_err("Error allocating hardware parameter structure: %s.",
- snd_strerror(ret));
- goto scan_error_cleanup;
- }
-
- ret = snd_pcm_hw_params_any(temp_handle, hw_params);
- if (ret < 0) {
- sr_err("Error initializing hardware parameter structure: %s.",
- snd_strerror(ret));
- goto scan_error_cleanup;
- }
-
- snd_pcm_hw_params_get_channels_max(hw_params, &channels);
-
- /*
- * We need to test if each samplerate between min and max is supported.
- * Unfortunately, ALSA won't just throw a list at us.
- */
- snd_pcm_hw_params_get_rate_min(hw_params, &minrate, 0);
- snd_pcm_hw_params_get_rate_max(hw_params, &maxrate, 0);
- for (i = 0, offset = 0; i < ARRAY_SIZE(rates); i++) {
- rate = rates[i];
- if (rate < minrate)
- continue;
- if (rate > maxrate)
- break;
- ret = snd_pcm_hw_params_test_rate(temp_handle, hw_params,
- rate, 0);
- if (ret >= 0)
- hwrates[offset++] = rate;
- }
- hwrates[offset++] = 0;
-
- if ((ret = snd_pcm_close(temp_handle)) < 0)
- sr_err("Failed to close device: %s.", snd_strerror(ret));
- temp_handle = NULL;
-
- /*
- * Now we are done querying the hardware parameters.
- * If we made it here, we know everything we want to know, and it's
- * time to create our sigrok device.
- */
- sr_info("Device %s has %d channels.", alsaname, channels);
- if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "ALSA:",
- cardname, snd_pcm_info_get_name(pcminfo)))) {
- sr_err("Failed to create device instance.");
- goto scan_error_cleanup;
- }
- if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
- sr_err("Device context malloc failed.");
- goto scan_error_cleanup;
- }
- if (!(devrates = g_try_malloc(offset * sizeof(uint64_t)))) {
- sr_err("Samplerate list malloc failed.");
- goto scan_error_cleanup;
- }
-
- devc->hwdev = g_strdup(alsaname);
- devc->num_channels = channels;
- devc->hw_params = hw_params;
- memcpy(devrates, hwrates, offset * sizeof(uint64_t));
- devc->samplerates = devrates;
-
- sdi->priv = devc;
- sdi->driver = di;
-
- for (i = 0; i < devc->num_channels; i++) {
- snprintf(p_name, sizeof(p_name), "Ch_%d", i);
- if (!(ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, p_name)))
- goto scan_error_cleanup;
- sdi->channels = g_slist_append(sdi->channels, ch);
- }
-
- drvc->instances = g_slist_append(drvc->instances, sdi);
- *devices = g_slist_append(*devices, sdi);
- return;
-
-scan_error_cleanup:
- if (devc) {
- if (devc->hwdev)
- g_free(devc->hwdev);
- g_free(devc);
- }
- if (devrates)
- g_free(devrates);
- if (sdi)
- sr_dev_inst_free(sdi);
- if (hw_params)
- snd_pcm_hw_params_free(hw_params);
- if (temp_handle)
- if ((ret = snd_pcm_close(temp_handle)) < 0) {
- sr_err("Failed to close device: %s.",
- snd_strerror(ret));
- }
-}
-
-/**
- * Scan all alsa devices, and translate them to sigrok devices.
- *
- * Each alsa device (not alsa card) gets its own sigrok device.
- *
- * For example,
- * hw:1,0 == sigrok device 0
- * hw:1,1 == sigrok device 1
- * hw:2,0 == sigrok device 2
- * hw:2,1 == sigrok device 3
- * hw:2,2 == sigrok device 4
- * [...]
- *
- * We don't currently look at alsa subdevices. We only use subdevice 0.
- * Every input device will have its own channels (left, right, etc). Each of
- * those channels gets mapped to a different sigrok channel. A device with 4
- * channels will have 4 channels from sigrok's perspective.
- */
-SR_PRIV GSList *alsa_scan(GSList *options, struct sr_dev_driver *di)
-{
- GSList *devices = NULL;
- snd_ctl_t *handle;
- int card, ret, dev;
- snd_ctl_card_info_t *info;
- snd_pcm_info_t *pcminfo;
- const char *cardname;
- char hwcard[32], hwdev[32];
-
- /* TODO */
- (void)options;
-
- if ((ret = snd_ctl_card_info_malloc(&info)) < 0) {
- sr_dbg("Failed to malloc card info: %s.", snd_strerror(ret));
- return NULL;
- }
- if ((ret = snd_pcm_info_malloc(&pcminfo) < 0)) {
- sr_dbg("Cannot malloc pcm info: %s.", snd_strerror(ret));
- return NULL;
- }
-
- card = -1;
- while (snd_card_next(&card) >= 0 && card >= 0) {
- snprintf(hwcard, sizeof(hwcard), "hw:%d", card);
- if ((ret = snd_ctl_open(&handle, hwcard, 0)) < 0) {
- sr_dbg("Cannot open (%d): %s.", card, snd_strerror(ret));
- continue;
- }
- if ((ret = snd_ctl_card_info(handle, info)) < 0) {
- sr_dbg("Cannot get hardware info (%d): %s.",
- card, snd_strerror(ret));
- if ((ret = snd_ctl_close(handle)) < 0) {
- sr_dbg("Cannot close device (%d): %s.",
- card, snd_strerror(ret));
- }
- continue;
- }
- dev = -1;
- while (snd_ctl_pcm_next_device(handle, &dev) >= 0 && dev >= 0) {
- snprintf(hwdev, sizeof(hwdev), "%s,%d", hwcard, dev);
- /*
- * TODO: We always use subdevice 0, but we have yet to
- * explore the possibilities opened up by other
- * subdevices. Most hardware only has subdevice 0.
- */
- snd_pcm_info_set_device(pcminfo, dev);
- snd_pcm_info_set_subdevice(pcminfo, 0);
- snd_pcm_info_set_stream(pcminfo,
- SND_PCM_STREAM_CAPTURE);
- if ((ret = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
- sr_dbg("Cannot get device info (%s): %s.",
- hwdev, snd_strerror(ret));
- continue;
- }
-
- cardname = snd_ctl_card_info_get_name(info);
- sr_info("card %d: %s [%s], device %d: %s [%s]",
- card, snd_ctl_card_info_get_id(info), cardname,
- dev, snd_pcm_info_get_id(pcminfo),
- snd_pcm_info_get_name(pcminfo));
-
- alsa_scan_handle_dev(&devices, cardname, hwdev,
- di, pcminfo);
- }
- if ((ret = snd_ctl_close(handle)) < 0) {
- sr_dbg("Cannot close device (%d): %s.",
- card, snd_strerror(ret));
- }
- }
-
- snd_pcm_info_free(pcminfo);
- snd_ctl_card_info_free(info);
-
- return devices;
-}
-
-/**
- * Set the samplerate of the ALSA device.
- *
- * Changes the samplerate of the given ALSA device if the specified samplerate
- * is supported by the hardware.
- *
- * The new samplerate is recorded, but it is not applied to the hardware. The
- * samplerate is applied to the hardware only when acquisition is started via
- * dev_acquisition_start(), and cannot be changed during acquisition. To change
- * the samplerate, several steps are needed:
- *
- * 1) If acquisition is running, it must first be stopped.
- * 2) dev_config_set() must be called with the new samplerate.
- * 3) When starting a new acquisition, the new samplerate is applied.
- *
- */
-SR_PRIV int alsa_set_samplerate(const struct sr_dev_inst *sdi,
- uint64_t newrate)
-{
- struct dev_context *devc;
- size_t i;
- uint64_t rate = 0;
-
- if (!(devc = sdi->priv))
- return SR_ERR_ARG;
-
- i = 0;
- do {
- if (newrate == devc->samplerates[i]) {
- rate = newrate;
- break;
- }
- } while (devc->samplerates[i++] != 0);
-
- if (!rate) {
- sr_err("Sample rate %" PRIu64 " not supported.", newrate);
- return SR_ERR_ARG;
- }
-
- devc->cur_samplerate = rate;
- return SR_OK;
-}
-
-SR_PRIV int alsa_receive_data(int fd, int revents, void *cb_data)
-{
- struct sr_dev_inst *sdi;
- struct dev_context *devc;
- struct sr_datafeed_packet packet;
- struct sr_datafeed_analog analog;
- int16_t inbuf[4096];
- int i, x, count, offset, samples_to_get;
- int16_t tmp16;
- const float s16norm = 1 / (float)(1 << 15);
-
- (void)fd;
- (void)revents;
-
- sdi = cb_data;
- devc = sdi->priv;
-
- memset(&analog, 0, sizeof(struct sr_datafeed_analog));
- memset(inbuf, 0, sizeof(inbuf));
-
- samples_to_get = MIN(4096 / 4, devc->limit_samples);
-
- sr_spew("Getting %d samples from audio device.", samples_to_get);
- count = snd_pcm_readi(devc->capture_handle, inbuf, samples_to_get);
-
- if (count < 0) {
- sr_err("Failed to read samples: %s.", snd_strerror(count));
- return FALSE;
- } else if (count != samples_to_get) {
- sr_spew("Only got %d/%d samples.", count, samples_to_get);
- }
-
- analog.data = g_try_malloc0(count * sizeof(float) * devc->num_channels);
- if (!analog.data) {
- sr_err("Failed to malloc sample buffer.");
- return FALSE;
- }
-
- offset = 0;
- /*
- * 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_channels) {
- for (x = 0; x < devc->num_channels; x++) {
- tmp16 = inbuf[i + x];
- analog.data[offset++] = tmp16 * s16norm;
- }
- }
-
- /* Send a sample packet with the analog values. */
- analog.channels = sdi->channels;
- analog.num_samples = count;
- analog.mq = SR_MQ_VOLTAGE; /* FIXME */
- analog.unit = SR_UNIT_VOLT; /* FIXME */
- packet.type = SR_DF_ANALOG;
- packet.payload = &analog;
- sr_session_send(devc->cb_data, &packet);
-
- g_free(analog.data);
-
- devc->num_samples += count;
-
- /* Stop acquisition if we acquired enough samples. */
- if (devc->limit_samples && devc->num_samples >= devc->limit_samples) {
- sr_info("Requested number of samples reached.");
- sdi->driver->dev_acquisition_stop(sdi, cb_data);
- }
-
- return TRUE;
-}