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