hardware/libaudio
修订版 | ce9a1b1c6983dbb91c592643d1d90d64786bbcbe (tree) |
---|---|
时间 | 2017-05-02 18:43:41 |
作者 | Valentin Manea <valy@mrs....> |
Commiter | Chih-Wei Huang |
select_card: only open PCM devices with the same type as requested
Let select_card() only open /dev/snd/pcmCxp for playback and /dev/snd/pcmCxc
for capture device. This way select_card won't try to open a device twice.
In some cases the second query on a playback device(even though
select_card is searching for a capture device) will block inside the
kernel causing audio to stop working.
@@ -183,6 +183,7 @@ struct snd_pcm_info *select_card(unsigned int device, unsigned int flags) | ||
183 | 183 | static struct snd_pcm_info *cached_info[4]; |
184 | 184 | struct snd_pcm_info *info; |
185 | 185 | int d = !!(flags & PCM_IN); |
186 | + char e = d ? 'c' : 'p'; | |
186 | 187 | if (!cached_info[d] && !cached_info[d + 2]) { |
187 | 188 | struct dirent **namelist; |
188 | 189 | char path[PATH_MAX] = "/dev/snd/"; |
@@ -191,7 +192,7 @@ struct snd_pcm_info *select_card(unsigned int device, unsigned int flags) | ||
191 | 192 | int i, fd; |
192 | 193 | for (i = 0; i < n; i++) { |
193 | 194 | struct dirent *de = namelist[i]; |
194 | - if (!strncmp(de->d_name, "pcmC", 4)) { | |
195 | + if (!strncmp(de->d_name, "pcmC", 4) && de->d_name[strlen(de->d_name) - 1] == e) { | |
195 | 196 | strcpy(path + 9, de->d_name); |
196 | 197 | if ((fd = open(path, O_RDWR)) >= 0) { |
197 | 198 | info = malloc(sizeof(*info)); |