2 * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <alsa/asoundlib.h>
20 #include "pbd/convert.h"
21 #include "ardouralsautil/deviceinfo.h"
26 ARDOUR::get_alsa_device_parameters (const char* device_name, const bool play, ALSADeviceInfo *nfo)
29 snd_pcm_hw_params_t *hw_params;
35 unsigned long min_psiz, max_psiz;
36 unsigned long min_bufz, max_bufz;
37 unsigned int min_nper, max_nper;
39 err = snd_pcm_open (&pcm, device_name,
40 play ? SND_PCM_STREAM_PLAYBACK : SND_PCM_STREAM_CAPTURE,
44 fprintf (stderr, "ALSA: Cannot open device '%s': %s\n", device_name, snd_strerror (err));
48 snd_pcm_hw_params_alloca (&hw_params);
49 err = snd_pcm_hw_params_any (pcm, hw_params);
51 errmsg = "Cannot get hardware parameters";
55 err = snd_pcm_hw_params_get_channels_max (hw_params, &nfo->max_channels);
57 errmsg = "Cannot get maximum channels count";
61 err = snd_pcm_hw_params_get_rate_min (hw_params, &nfo->min_rate, NULL);
63 errmsg = "Cannot get minimum rate";
66 err = snd_pcm_hw_params_get_rate_max (hw_params, &nfo->max_rate, NULL);
68 errmsg = "Cannot get maximum rate";
72 err = snd_pcm_hw_params_get_period_size_min (hw_params, &min_psiz, 0);
74 errmsg = "Cannot get minimum period size";
77 err = snd_pcm_hw_params_get_period_size_max (hw_params, &max_psiz, 0);
79 errmsg = "Cannot get maximum period size";
83 err = snd_pcm_hw_params_get_buffer_size_min (hw_params, &min_bufz);
85 errmsg = "Cannot get minimum buffer size";
88 err = snd_pcm_hw_params_get_buffer_size_max (hw_params, &max_bufz);
90 errmsg = "Cannot get maximum buffer size";
94 err = snd_pcm_hw_params_get_periods_min (hw_params, &min_nper, 0);
96 errmsg = "Cannot get minimum period count";
99 err = snd_pcm_hw_params_get_periods_max (hw_params, &max_nper, 0);
101 errmsg = "Cannot get maximum period count";
107 /* see also libs/backends/alsa/zita-alsa-pcmi.cc
108 * If any debug parameter is set, print device info.
110 if (getenv ("ZITA_ALSA_PCMI_DEBUG")) {
111 fprintf (stdout, "ALSA: *%s* device-info\n", play ? "playback" : "capture");
112 fprintf (stdout, " dev_name : %s\n", device_name);
113 fprintf (stdout, " channels : %u\n", nfo->max_channels);
114 fprintf (stdout, " min_rate : %u\n", nfo->min_rate);
115 fprintf (stdout, " max_rate : %u\n", nfo->max_rate);
116 fprintf (stdout, " min_psiz : %lu\n", nfo->min_size);
117 fprintf (stdout, " max_psiz : %lu\n", nfo->max_size);
118 fprintf (stdout, " min_bufz : %lu\n", min_bufz);
119 fprintf (stdout, " max_bufz : %lu\n", max_bufz);
120 fprintf (stdout, " min_nper : %d\n", min_nper);
121 fprintf (stdout, " max_nper : %d\n", max_nper);
122 fprintf (stdout, " possible : %lu .. %lu\n", nfo->min_size, nfo->max_size);
125 /* AlsaAudioBackend supports n-periods 2, 3 */
126 if (min_nper > 2 || max_nper < 3) {
127 errmsg = "Unsupported period count";
131 nfo->min_size = std::max (min_psiz, min_bufz / 3);
132 nfo->max_size = std::min (max_psiz, max_bufz / 2);
137 fprintf (stderr, "ALSA: %s: %s\n", errmsg.c_str(), snd_strerror (err));