]> sigrok.org Git - libsigrok.git/blame - hardware/alsa/protocol.c
alsa: Do not use snd_pcm_hw_params_set_rate_near()
[libsigrok.git] / hardware / alsa / protocol.c
CommitLineData
9cd9f6b7
AG
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2011 Daniel Ribeiro <drwyrm@gmail.com>
5 * Copyright (C) 2012 Uwe Hermann <uwe@hermann-uwe.de>
6 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "protocol.h"
24#include "libsigrok.h"
25#include "libsigrok-internal.h"
26
27SR_PRIV int alsa_receive_data(int fd, int revents, void *cb_data)
28{
29 struct sr_dev_inst *sdi;
30 struct dev_context *devc;
31 struct sr_datafeed_packet packet;
32 struct sr_datafeed_analog analog;
33 char inbuf[4096];
34 int i, x, count, offset, samples_to_get;
35 uint16_t tmp16;
36
37 (void)fd;
38 (void)revents;
39
40 sdi = cb_data;
41 devc = sdi->priv;
42
43 memset(&analog, 0, sizeof(struct sr_datafeed_analog));
44 memset(inbuf, 0, sizeof(inbuf));
45
46 samples_to_get = MIN(4096 / 4, devc->limit_samples);
47
48 sr_spew("Getting %d samples from audio device.", samples_to_get);
49 count = snd_pcm_readi(devc->capture_handle, inbuf, samples_to_get);
50
51 if (count < 0) {
52 sr_err("Failed to read samples: %s.", snd_strerror(count));
53 return FALSE;
54 } else if (count != samples_to_get) {
55 sr_spew("Only got %d/%d samples.", count, samples_to_get);
56 }
57
58 analog.data = g_try_malloc0(count * sizeof(float) * devc->num_probes);
59 if (!analog.data) {
60 sr_err("Failed to malloc sample buffer.");
61 return FALSE;
62 }
63
64 offset = 0;
65
66 for (i = 0; i < count; i++) {
67 for (x = 0; x < devc->num_probes; x++) {
68 tmp16 = *(uint16_t *)(inbuf + (i * 4) + (x * 2));
69 analog.data[offset++] = (float)tmp16;
70 }
71 }
72
73 /* Send a sample packet with the analog values. */
74 analog.num_samples = count;
75 analog.mq = SR_MQ_VOLTAGE; /* FIXME */
76 analog.unit = SR_UNIT_VOLT; /* FIXME */
77 packet.type = SR_DF_ANALOG;
78 packet.payload = &analog;
79 sr_session_send(devc->cb_data, &packet);
80
81 g_free(analog.data);
82
83 devc->num_samples += count;
84
85 /* Stop acquisition if we acquired enough samples. */
35e199da
UH
86 if (devc->limit_samples && devc->num_samples >= devc->limit_samples) {
87 sr_info("Requested number of samples reached.");
88 sdi->driver->dev_acquisition_stop(sdi, cb_data);
9cd9f6b7
AG
89 }
90
91 return TRUE;
92}