]> sigrok.org Git - libsigrok.git/blame - hardware/alsa/protocol.c
Replace 'probe' with 'channel' in most places.
[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
9cd9f6b7
AG
23#include "libsigrok.h"
24#include "libsigrok-internal.h"
721ecf3d 25#include "protocol.h"
9cd9f6b7 26
65faa197
AG
27/*
28 * There is no way to get a list of supported samplerates from ALSA. We could
29 * use the 'plughw' interface of ALSA, in which case any format and/or
30 * samplerate conversion would be performed by ALSA. However, we are interested
31 * in the hardware capabilities, and have the infrastructure in sigrok to do so.
32 * We therefore use the 'hw' interface. The downside is that the code gets a
33 * little bulkier, as we have to keep track of the hardware capabilities, and
34 * only use those that the hardware supports. Case in point, ALSA will not give
35 * us a list of capabilities; we have to test for each one individually. Hence,
36 * we keep lists of the capabilities we are interested in.
37 */
38static const unsigned int rates[] = {
39 5512,
40 8000,
41 11025,
21d3d4ee 42 12000,
65faa197
AG
43 16000,
44 22050,
21d3d4ee 45 24000,
65faa197
AG
46 32000,
47 44100,
48 48000,
49 64000,
50 88200,
51 96000,
52 176400,
53 192000,
21d3d4ee
UH
54 384000,
55 768000, /* Yes, there are sound cards that go this high. */
65faa197
AG
56};
57
6944b2d0
AG
58static void alsa_scan_handle_dev(GSList **devices,
59 const char *cardname, const char *alsaname,
60 struct sr_dev_driver *di,
61 snd_pcm_info_t *pcminfo)
62{
63 struct drv_context *drvc = NULL;
64 struct sr_dev_inst *sdi = NULL;
65 struct dev_context *devc = NULL;
ba7dd8bb 66 struct sr_channel *ch;
6944b2d0 67 int ret;
65faa197
AG
68 unsigned int i, offset, channels, minrate, maxrate, rate;
69 uint64_t hwrates[ARRAY_SIZE(rates)];
70 uint64_t *devrates = NULL;
6944b2d0
AG
71 snd_pcm_t *temp_handle = NULL;
72 snd_pcm_hw_params_t *hw_params = NULL;
721ecf3d 73 char p_name[32];
6944b2d0
AG
74
75 drvc = di->priv;
76
77 /*
65faa197 78 * Get hardware parameters:
ba7dd8bb 79 * The number of channels, for example, are our sigrok channels. Getting
65faa197
AG
80 * this information needs a detour. We need to open the device, then
81 * query it and/or test different parameters. A side-effect of is that
82 * we create a snd_pcm_hw_params_t object. We take advantage of the
6944b2d0
AG
83 * situation, and pass this object in our dev_context->hw_params,
84 * eliminating the need to free() it and malloc() it later.
85 */
86 ret = snd_pcm_open(&temp_handle, alsaname, SND_PCM_STREAM_CAPTURE, 0);
87 if (ret < 0) {
88 sr_err("Cannot open device: %s.", snd_strerror(ret));
89 goto scan_error_cleanup;
90 }
91
92 ret = snd_pcm_hw_params_malloc(&hw_params);
93 if (ret < 0) {
94 sr_err("Error allocating hardware parameter structure: %s.",
95 snd_strerror(ret));
96 goto scan_error_cleanup;
97 }
98
99 ret = snd_pcm_hw_params_any(temp_handle, hw_params);
100 if (ret < 0) {
101 sr_err("Error initializing hardware parameter structure: %s.",
102 snd_strerror(ret));
103 goto scan_error_cleanup;
104 }
105
106 snd_pcm_hw_params_get_channels_max(hw_params, &channels);
107
65faa197
AG
108 /*
109 * We need to test if each samplerate between min and max is supported.
110 * Unfortunately, ALSA won't just throw a list at us.
111 */
112 snd_pcm_hw_params_get_rate_min(hw_params, &minrate, 0);
113 snd_pcm_hw_params_get_rate_max(hw_params, &maxrate, 0);
721ecf3d 114 for (i = 0, offset = 0; i < ARRAY_SIZE(rates); i++) {
65faa197
AG
115 rate = rates[i];
116 if (rate < minrate)
117 continue;
118 if (rate > maxrate)
119 break;
120 ret = snd_pcm_hw_params_test_rate(temp_handle, hw_params,
121 rate, 0);
122 if (ret >= 0)
123 hwrates[offset++] = rate;
124 }
125 hwrates[offset++] = 0;
126
52ba6e05
UH
127 if ((ret = snd_pcm_close(temp_handle)) < 0)
128 sr_err("Failed to close device: %s.", snd_strerror(ret));
6944b2d0
AG
129 temp_handle = NULL;
130
131 /*
65faa197 132 * Now we are done querying the hardware parameters.
721ecf3d
UH
133 * If we made it here, we know everything we want to know, and it's
134 * time to create our sigrok device.
6944b2d0
AG
135 */
136 sr_info("Device %s has %d channels.", alsaname, channels);
137 if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "ALSA:",
138 cardname, snd_pcm_info_get_name(pcminfo)))) {
721ecf3d 139 sr_err("Failed to create device instance.");
6944b2d0
AG
140 goto scan_error_cleanup;
141 }
142 if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
143 sr_err("Device context malloc failed.");
144 goto scan_error_cleanup;
145 }
65faa197
AG
146 if (!(devrates = g_try_malloc(offset * sizeof(uint64_t)))) {
147 sr_err("Samplerate list malloc failed.");
148 goto scan_error_cleanup;
149 }
6944b2d0
AG
150
151 devc->hwdev = g_strdup(alsaname);
ba7dd8bb 152 devc->num_channels = channels;
6944b2d0 153 devc->hw_params = hw_params;
65faa197 154 memcpy(devrates, hwrates, offset * sizeof(uint64_t));
aa0dbd68 155 devc->samplerates = devrates;
65faa197 156
6944b2d0
AG
157 sdi->priv = devc;
158 sdi->driver = di;
159
ba7dd8bb 160 for (i = 0; i < devc->num_channels; i++) {
6944b2d0 161 snprintf(p_name, sizeof(p_name), "Ch_%d", i);
ba7dd8bb 162 if (!(ch = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, p_name)))
6944b2d0 163 goto scan_error_cleanup;
ba7dd8bb 164 sdi->channels = g_slist_append(sdi->channels, ch);
6944b2d0
AG
165 }
166
167 drvc->instances = g_slist_append(drvc->instances, sdi);
168 *devices = g_slist_append(*devices, sdi);
169 return;
170
171scan_error_cleanup:
172 if (devc) {
173 if (devc->hwdev)
721ecf3d 174 g_free(devc->hwdev);
6944b2d0
AG
175 g_free(devc);
176 }
65faa197
AG
177 if (devrates)
178 g_free(devrates);
6944b2d0
AG
179 if (sdi)
180 sr_dev_inst_free(sdi);
181 if (hw_params)
182 snd_pcm_hw_params_free(hw_params);
183 if (temp_handle)
52ba6e05
UH
184 if ((ret = snd_pcm_close(temp_handle)) < 0) {
185 sr_err("Failed to close device: %s.",
186 snd_strerror(ret));
187 }
6944b2d0
AG
188}
189
190/**
721ecf3d
UH
191 * Scan all alsa devices, and translate them to sigrok devices.
192 *
193 * Each alsa device (not alsa card) gets its own sigrok device.
6944b2d0 194 *
6944b2d0
AG
195 * For example,
196 * hw:1,0 == sigrok device 0
197 * hw:1,1 == sigrok device 1
198 * hw:2,0 == sigrok device 2
199 * hw:2,1 == sigrok device 3
200 * hw:2,2 == sigrok device 4
201 * [...]
721ecf3d 202 *
6944b2d0 203 * We don't currently look at alsa subdevices. We only use subdevice 0.
721ecf3d 204 * Every input device will have its own channels (left, right, etc). Each of
ba7dd8bb
UH
205 * those channels gets mapped to a different sigrok channel. A device with 4
206 * channels will have 4 channels from sigrok's perspective.
6944b2d0
AG
207 */
208SR_PRIV GSList *alsa_scan(GSList *options, struct sr_dev_driver *di)
209{
210 GSList *devices = NULL;
211 snd_ctl_t *handle;
212 int card, ret, dev;
213 snd_ctl_card_info_t *info;
214 snd_pcm_info_t *pcminfo;
721ecf3d
UH
215 const char *cardname;
216 char hwcard[32], hwdev[32];
217
6944b2d0
AG
218 /* TODO */
219 (void)options;
220
52ba6e05 221 if ((ret = snd_ctl_card_info_malloc(&info)) < 0) {
3d6de074 222 sr_dbg("Failed to malloc card info: %s.", snd_strerror(ret));
6944b2d0
AG
223 return NULL;
224 }
52ba6e05 225 if ((ret = snd_pcm_info_malloc(&pcminfo) < 0)) {
3d6de074 226 sr_dbg("Cannot malloc pcm info: %s.", snd_strerror(ret));
6944b2d0
AG
227 return NULL;
228 }
229
230 card = -1;
231 while (snd_card_next(&card) >= 0 && card >= 0) {
6944b2d0
AG
232 snprintf(hwcard, sizeof(hwcard), "hw:%d", card);
233 if ((ret = snd_ctl_open(&handle, hwcard, 0)) < 0) {
3d6de074 234 sr_dbg("Cannot open (%d): %s.", card, snd_strerror(ret));
6944b2d0
AG
235 continue;
236 }
237 if ((ret = snd_ctl_card_info(handle, info)) < 0) {
3d6de074 238 sr_dbg("Cannot get hardware info (%d): %s.",
6944b2d0 239 card, snd_strerror(ret));
52ba6e05 240 if ((ret = snd_ctl_close(handle)) < 0) {
3d6de074 241 sr_dbg("Cannot close device (%d): %s.",
52ba6e05
UH
242 card, snd_strerror(ret));
243 }
6944b2d0
AG
244 continue;
245 }
246 dev = -1;
247 while (snd_ctl_pcm_next_device(handle, &dev) >= 0 && dev >= 0) {
6944b2d0
AG
248 snprintf(hwdev, sizeof(hwdev), "%s,%d", hwcard, dev);
249 /*
250 * TODO: We always use subdevice 0, but we have yet to
251 * explore the possibilities opened up by other
252 * subdevices. Most hardware only has subdevice 0.
253 */
254 snd_pcm_info_set_device(pcminfo, dev);
255 snd_pcm_info_set_subdevice(pcminfo, 0);
256 snd_pcm_info_set_stream(pcminfo,
257 SND_PCM_STREAM_CAPTURE);
258 if ((ret = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
3d6de074 259 sr_dbg("Cannot get device info (%s): %s.",
52ba6e05 260 hwdev, snd_strerror(ret));
6944b2d0
AG
261 continue;
262 }
263
264 cardname = snd_ctl_card_info_get_name(info);
721ecf3d 265 sr_info("card %d: %s [%s], device %d: %s [%s]",
6944b2d0
AG
266 card, snd_ctl_card_info_get_id(info), cardname,
267 dev, snd_pcm_info_get_id(pcminfo),
268 snd_pcm_info_get_name(pcminfo));
269
270 alsa_scan_handle_dev(&devices, cardname, hwdev,
271 di, pcminfo);
272 }
52ba6e05 273 if ((ret = snd_ctl_close(handle)) < 0) {
3d6de074 274 sr_dbg("Cannot close device (%d): %s.",
52ba6e05
UH
275 card, snd_strerror(ret));
276 }
6944b2d0
AG
277 }
278
279 snd_pcm_info_free(pcminfo);
280 snd_ctl_card_info_free(info);
281
282 return devices;
283}
284
721ecf3d
UH
285/**
286 * Set the samplerate of the ALSA device.
65faa197
AG
287 *
288 * Changes the samplerate of the given ALSA device if the specified samplerate
289 * is supported by the hardware.
721ecf3d 290 *
65faa197
AG
291 * The new samplerate is recorded, but it is not applied to the hardware. The
292 * samplerate is applied to the hardware only when acquisition is started via
293 * dev_acquisition_start(), and cannot be changed during acquisition. To change
294 * the samplerate, several steps are needed:
721ecf3d 295 *
65faa197
AG
296 * 1) If acquisition is running, it must first be stopped.
297 * 2) dev_config_set() must be called with the new samplerate.
298 * 3) When starting a new acquisition, the new samplerate is applied.
721ecf3d 299 *
65faa197
AG
300 */
301SR_PRIV int alsa_set_samplerate(const struct sr_dev_inst *sdi,
721ecf3d 302 uint64_t newrate)
65faa197
AG
303{
304 struct dev_context *devc;
305 size_t i;
306 uint64_t rate = 0;
307
308 if (!(devc = sdi->priv))
309 return SR_ERR_ARG;
310
311 i = 0;
312 do {
aa0dbd68 313 if (newrate == devc->samplerates[i]) {
65faa197
AG
314 rate = newrate;
315 break;
316 }
aa0dbd68 317 } while (devc->samplerates[i++] != 0);
65faa197
AG
318
319 if (!rate) {
a1b9a9bf 320 sr_err("Sample rate %" PRIu64 " not supported.", newrate);
65faa197
AG
321 return SR_ERR_ARG;
322 }
323
324 devc->cur_samplerate = rate;
325 return SR_OK;
326}
327
9cd9f6b7
AG
328SR_PRIV int alsa_receive_data(int fd, int revents, void *cb_data)
329{
330 struct sr_dev_inst *sdi;
331 struct dev_context *devc;
332 struct sr_datafeed_packet packet;
333 struct sr_datafeed_analog analog;
729850c9 334 int16_t inbuf[4096];
9cd9f6b7 335 int i, x, count, offset, samples_to_get;
729850c9 336 int16_t tmp16;
721ecf3d 337 const float s16norm = 1 / (float)(1 << 15);
9cd9f6b7
AG
338
339 (void)fd;
340 (void)revents;
341
342 sdi = cb_data;
343 devc = sdi->priv;
344
345 memset(&analog, 0, sizeof(struct sr_datafeed_analog));
346 memset(inbuf, 0, sizeof(inbuf));
347
348 samples_to_get = MIN(4096 / 4, devc->limit_samples);
349
350 sr_spew("Getting %d samples from audio device.", samples_to_get);
351 count = snd_pcm_readi(devc->capture_handle, inbuf, samples_to_get);
352
353 if (count < 0) {
354 sr_err("Failed to read samples: %s.", snd_strerror(count));
355 return FALSE;
356 } else if (count != samples_to_get) {
357 sr_spew("Only got %d/%d samples.", count, samples_to_get);
358 }
359
ba7dd8bb 360 analog.data = g_try_malloc0(count * sizeof(float) * devc->num_channels);
9cd9f6b7
AG
361 if (!analog.data) {
362 sr_err("Failed to malloc sample buffer.");
363 return FALSE;
364 }
365
366 offset = 0;
729850c9
AG
367 /*
368 * It's impossible to know what voltage levels the soundcard handles.
369 * Some handle 0 dBV rms, some 0dBV peak-to-peak, +4dbmW (600 ohm), etc
370 * Each of these corresponds to a different voltage, and there is no
371 * mechanism to determine this voltage. The best solution is to send all
372 * audio data as a normalized float, and let the frontend or user worry
373 * about the calibration.
374 */
ba7dd8bb
UH
375 for (i = 0; i < count; i += devc->num_channels) {
376 for (x = 0; x < devc->num_channels; x++) {
721ecf3d 377 tmp16 = inbuf[i + x];
729850c9 378 analog.data[offset++] = tmp16 * s16norm;
9cd9f6b7
AG
379 }
380 }
381
382 /* Send a sample packet with the analog values. */
ba7dd8bb 383 analog.channels = sdi->channels;
9cd9f6b7
AG
384 analog.num_samples = count;
385 analog.mq = SR_MQ_VOLTAGE; /* FIXME */
386 analog.unit = SR_UNIT_VOLT; /* FIXME */
387 packet.type = SR_DF_ANALOG;
388 packet.payload = &analog;
389 sr_session_send(devc->cb_data, &packet);
390
391 g_free(analog.data);
392
393 devc->num_samples += count;
394
395 /* Stop acquisition if we acquired enough samples. */
35e199da
UH
396 if (devc->limit_samples && devc->num_samples >= devc->limit_samples) {
397 sr_info("Requested number of samples reached.");
398 sdi->driver->dev_acquisition_stop(sdi, cb_data);
9cd9f6b7
AG
399 }
400
401 return TRUE;
402}