• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

hardware/libaudio


コミットメタ情報

リビジョンcea954f274111f7b63a6d79f3dc697a24297b0c3 (tree)
日時2016-08-05 18:21:00
作者Chih-Wei Huang <cwhuang@linu...>
コミッターChih-Wei Huang

ログメッセージ

audio_hw: search sound card more properly

Scan /dev/snd/ to find the appropriate sound card.
Ignore IntelHDMI since it's handled by another HAL.

変更サマリ

差分

--- a/audio_hw.c
+++ b/audio_hw.c
@@ -17,7 +17,9 @@
1717 #define LOG_TAG "audio_hw_primary"
1818 /*#define LOG_NDEBUG 0*/
1919
20+#include <dirent.h>
2021 #include <errno.h>
22+#include <fcntl.h>
2123 #include <pthread.h>
2224 #include <stdint.h>
2325 #include <stdlib.h>
@@ -32,6 +34,8 @@
3234
3335 #include <system/audio.h>
3436
37+#include <linux/ioctl.h>
38+#include <sound/asound.h>
3539 #include <tinyalsa/asoundlib.h>
3640
3741 #include <audio_utils/resampler.h>
@@ -173,30 +177,62 @@ static void release_buffer(struct resampler_buffer_provider *buffer_provider,
173177
174178 /* Helper functions */
175179
176-static int select_card(int d)
180+struct snd_pcm_info *select_card(unsigned int device __unused, unsigned int flags)
177181 {
178- int i;
179- char dname[32];
180- for (i = 0; i < 3; ++i) {
181- sprintf(dname, "/dev/snd/pcmC%dD0%c", i, (d == PCM_IN) ? 'c' : 'p');
182- if (!access(dname, R_OK | W_OK)) {
183- ALOGD("found %s %s", (d == PCM_IN) ? "in" : "out", dname);
184- return i;
182+ static struct snd_pcm_info *cached_info[2];
183+ int d = !!(flags & PCM_IN);
184+ if (!cached_info[d]) {
185+ struct dirent **namelist;
186+ char path[PATH_MAX] = "/dev/snd/";
187+ int n = scandir(path, &namelist, NULL, alphasort);
188+ if (n >= 0) {
189+ int i, fd;
190+ struct snd_pcm_info *info = malloc(sizeof(*info));
191+ for (i = 0; i < n; i++) {
192+ struct dirent *de = namelist[i];
193+ if (!cached_info[d] && !strncmp(de->d_name, "pcmC", 4)) {
194+ strcpy(path + 9, de->d_name);
195+ if ((fd = open(path, O_RDWR)) >= 0) {
196+ if (!ioctl(fd, SNDRV_PCM_IOCTL_INFO, info)) {
197+ if (info->stream == d && /* ignore IntelHDMI */
198+ !strstr((const char *)info->id, "IntelHDMI")) {
199+ ALOGD("found audio %s at %s\ncard: %d/%d id: %s\nname: %s\nsubname: %s\nstream: %d",
200+ d ? "in" : "out", path,
201+ info->card, info->device, info->id,
202+ info->name, info->subname, info->stream);
203+ cached_info[d] = info;
204+ }
205+ } else {
206+ ALOGV("can't get info of %s", path);
207+ }
208+ close(fd);
209+ }
210+ }
211+ free(de);
212+ }
213+ free(namelist);
214+ if (!cached_info[d]) {
215+ free(info);
216+ }
185217 }
186218 }
187- ALOGE("no pcm card found!");
188- return -1;
219+ return cached_info[d];
189220 }
190221
191-struct pcm *my_pcm_open(unsigned int card, unsigned int device, unsigned int flags, struct pcm_config *config)
222+struct pcm *my_pcm_open(unsigned int device, unsigned int flags, struct pcm_config *config)
192223 {
193- struct pcm *pcm = pcm_open(card, device, flags, config);
224+ struct snd_pcm_info *info = select_card(device, flags);
225+ if (!info) {
226+ ALOGE("unable to find a sound card");
227+ return NULL;
228+ }
229+ struct pcm *pcm = pcm_open(info->card, info->device, flags, config);
194230 if (pcm && !pcm_is_ready(pcm)) {
195231 ALOGE("my_pcm_open(%d) failed: %s", flags, pcm_get_error(pcm));
196232 pcm_close(pcm);
197- ALOGI("my_pcm_open: re-try 44100 on card %d", card);
233+ ALOGI("my_pcm_open: re-try 44100 on card %d/%d", info->card, info->device);
198234 config->rate = 44100;
199- pcm = pcm_open(card, device, flags, config);
235+ pcm = pcm_open(info->card, info->device, flags, config);
200236 }
201237 return pcm;
202238 }
@@ -317,13 +353,10 @@ static int start_output_stream(struct stream_out *out)
317353 pthread_mutex_unlock(&in->lock);
318354 }
319355
320- ret = select_card(PCM_OUT);
321- if (ret < 0) {
356+ out->pcm = my_pcm_open(device, PCM_OUT | PCM_NORESTART, out->pcm_config);
357+ if (!out->pcm) {
322358 return -ENODEV;
323- }
324- out->pcm = my_pcm_open(ret, device, PCM_OUT | PCM_NORESTART, out->pcm_config);
325-
326- if (out->pcm && !pcm_is_ready(out->pcm)) {
359+ } else if (!pcm_is_ready(out->pcm)) {
327360 ALOGE("pcm_open(out) failed: %s", pcm_get_error(out->pcm));
328361 pcm_close(out->pcm);
329362 return -ENOMEM;
@@ -389,13 +422,10 @@ static int start_input_stream(struct stream_in *in)
389422 pthread_mutex_unlock(&out->lock);
390423 }
391424
392- ret = select_card(PCM_IN);
393- if (ret < 0) {
425+ in->pcm = my_pcm_open(device, PCM_IN, in->pcm_config);
426+ if (!in->pcm) {
394427 return -ENODEV;
395- }
396- in->pcm = my_pcm_open(ret, device, PCM_IN, in->pcm_config);
397-
398- if (in->pcm && !pcm_is_ready(in->pcm)) {
428+ } else if (!pcm_is_ready(in->pcm)) {
399429 ALOGE("pcm_open(in) failed: %s", pcm_get_error(in->pcm));
400430 pcm_close(in->pcm);
401431 return -ENOMEM;
@@ -1028,6 +1058,9 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
10281058 struct stream_out *out;
10291059 int ret;
10301060
1061+ if (!select_card(0, PCM_OUT))
1062+ return -ENODEV;
1063+
10311064 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
10321065 if (!out)
10331066 return -ENOMEM;