如何在不重启应用程序的情况下使asound.conf得配置生效?

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的时间戳

touch usr/share/alsa/alsa.conf

你可能感兴趣的:(linux,alsa,嵌入式软件,linux,音视频)