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