1.在某些应用场景中会遇到需要在程序动态切audio output的情况,比如在一个应用播到tdmc out时,可能需要把应用的输出改到spdif,这时会想到暂停播放,close声卡,改asound.conf的配置,再继续播放重新打开声卡,但是发现并没有生效,声卡还是用的修改之前的配置,原因是因为,alsa.conf的时间戳没有变:
pcm.c
2664 int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
2665 snd_pcm_stream_t stream, int mode)
2666 {
2667 snd_config_t *top;
2668 int err;
2669
2670 assert(pcmp && name);
2671 err = snd_config_update_ref(&top); // alsa打开pcm设备的时候有更新配置的动作
2672 if (err < 0)
2673 return err;
2674 err = snd_pcm_open_noupdate(pcmp, top, name, stream, mode, 0);
2675 snd_config_unref(top);
2676 return err;
2677 }
conf.c
4165 int snd_config_update_ref(snd_config_t **top)
4166 {
4167 int err;
4168
4169 if (top)
4170 *top = NULL;
4171 snd_config_lock();
4172 err = snd_config_update_r(&snd_config, &snd_config_global_update, NULL); //这里是重新读配置文件去更新配置
4173 if (err >= 0) {
4174 if (snd_config) {
4175 if (top) {
4176 snd_config->refcount++;
4177 *top = snd_config;
4178 }
4179 } else {
4180 err = -ENODEV;
4181 }
4182 }
4183 snd_config_unlock();
4184 return err;
4185 }
conf.c
3983 int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, const char *cfgs)
3984 {
......
4040 for (k = 0; k < local->count; ++k) {
4041 struct stat st;
4042 struct finfo *lf = &local->finfo[k];
4043 if (stat(lf->name, &st) >= 0) { // 通过stat函数读取文件的时间戳,会去读取usr/share/alsa/alsa.conf 这个配置文件的时间戳
4044 lf->dev = st.st_dev;
4045 lf->ino = st.st_ino;
4046 lf->mtime = st.st_mtime;
4047 } else {
4048 SNDERR("Cannot access file %s", lf->name);
4049 free(lf->name);
4050 memmove(&local->finfo[k], &local->finfo[k+1], sizeof(struct finfo) * (local->count - k - 1));
4051 k--;
4052 local->count--;
4053 }
4054 }
4055 if (!update)
4056 goto _reread;
4057 if (local->count != update->count)
4058 goto _reread;
4059 for (k = 0; k < local->count; ++k) {
4060 struct finfo *lf = &local->finfo[k];
4061 struct finfo *uf = &update->finfo[k];
4062 if (strcmp(lf->name, uf->name) != 0 ||
4063 lf->dev != uf->dev ||
4064 lf->ino != uf->ino ||
4065 lf->mtime != uf->mtime)
4066 goto _reread; // 如果判断时间戳变了就跳转_reread,重新读配置文件
4067 }
......
4085 _reread:
4086 *_top = NULL;
4087 *_update = NULL;
4088 if (update) {
4089 snd_config_update_free(update);
4090 update = NULL;
4091 }
4092 if (top) {
4093 snd_config_delete(top);
4094 top = NULL;
4095 }
4096 err = snd_config_top(&top);
4097 if (err < 0)
4098 goto _end;
4099 if (!local)
4100 goto _skip;
4101 for (k = 0; k < local->count; ++k) {
4102 snd_input_t *in;
4103 err = snd_input_stdio_open(&in, local->finfo[k].name, "r");
4104 if (err >= 0) {
4105 err = snd_config_load(top, in);
4106 snd_input_close(in);
4107 if (err < 0) {
4108 SNDERR("%s may be old or corrupted: consider to remove or fix it", local->finfo[k].name);
4109 goto _end;
4110 }
4111 } else {
4112 SNDERR("cannot access file %s", local->finfo[k].name);
4113 }
4114 }
......
}
所以只要在cloase 声卡后,再执行以下命令,重新打开声卡,asound.conf的更新就会生效
更新alsa.conf的时间戳
|