((dmix->slave_hw_ptr / dmix->slave_period_size) *
dmix->slave_period_size);
}
+
+int _snd_pcm_direct_new(snd_pcm_t **pcmp, snd_pcm_direct_t **_dmix, int type,
+ const char *name, struct snd_pcm_direct_open_conf *opts,
+ struct slave_params *params, snd_pcm_stream_t stream, int mode)
+{
+ snd_pcm_direct_t *dmix;
+ int fail_sem_loop = 10;
+ int ret;
+
+ dmix = calloc(1, sizeof(snd_pcm_direct_t));
+ if (!dmix)
+ return -ENOMEM;
+
+ ret = snd_pcm_direct_parse_bindings(dmix, params, opts->bindings);
+ if (ret < 0) {
+ free(dmix);
+ return ret;
+ }
+
+ dmix->ipc_key = opts->ipc_key;
+ dmix->ipc_perm = opts->ipc_perm;
+ dmix->ipc_gid = opts->ipc_gid;
+ dmix->tstamp_type = opts->tstamp_type;
+ dmix->semid = -1;
+ dmix->shmid = -1;
+ dmix->shmptr = (void *) -1;
+ dmix->type = type;
+
+ ret = snd_pcm_new(pcmp, type, name, stream, mode);
+ if (ret < 0) {
+_err_nosem:
+ free(dmix->bindings);
+ free(dmix);
+ return ret;
+ }
+
+ while (1) {
+ ret = snd_pcm_direct_semaphore_create_or_connect(dmix);
+ if (ret < 0) {
+ SNDERR("unable to create IPC semaphore");
+ goto _err_nosem;
+ }
+ ret = snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
+ if (ret < 0) {
+ snd_pcm_direct_semaphore_discard(dmix);
+ if (--fail_sem_loop <= 0)
+ goto _err_nosem;
+ continue;
+ }
+ break;
+ }
+
+ ret = snd_pcm_direct_shm_create_or_connect(dmix);
+ if (ret < 0) {
+ SNDERR("unable to create IPC shm instance");
+ snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
+ goto _err_nosem;
+ } else {
+ *_dmix = dmix;
+ }
+
+ return ret;
+}
};
int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf, int stream, struct snd_pcm_direct_open_conf *rec);
+
+int _snd_pcm_direct_new(snd_pcm_t **pcmp, snd_pcm_direct_t **_dmix, int type,
+ const char *name, struct snd_pcm_direct_open_conf *opts,
+ struct slave_params *params, snd_pcm_stream_t stream, int mode);
snd_pcm_stream_t stream, int mode)
{
snd_pcm_t *pcm = NULL, *spcm = NULL;
- snd_pcm_direct_t *dmix = NULL;
+ snd_pcm_direct_t *dmix;
int ret, first_instance;
- int fail_sem_loop = 10;
assert(pcmp);
return -EINVAL;
}
- dmix = calloc(1, sizeof(snd_pcm_direct_t));
- if (!dmix) {
- ret = -ENOMEM;
- goto _err_nosem;
- }
-
- ret = snd_pcm_direct_parse_bindings(dmix, params, opts->bindings);
+ ret = _snd_pcm_direct_new(pcmp, &dmix, SND_PCM_TYPE_DMIX, name, opts, params, stream, mode);
if (ret < 0)
- goto _err_nosem;
-
- dmix->ipc_key = opts->ipc_key;
- dmix->ipc_perm = opts->ipc_perm;
- dmix->ipc_gid = opts->ipc_gid;
- dmix->tstamp_type = opts->tstamp_type;
- dmix->semid = -1;
- dmix->shmid = -1;
-
- ret = snd_pcm_new(&pcm, dmix->type = SND_PCM_TYPE_DMIX, name, stream, mode);
- if (ret < 0)
- goto _err;
+ return ret;
+ first_instance = ret;
-
- while (1) {
- ret = snd_pcm_direct_semaphore_create_or_connect(dmix);
- if (ret < 0) {
- SNDERR("unable to create IPC semaphore");
- goto _err_nosem;
- }
- ret = snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
- if (ret < 0) {
- snd_pcm_direct_semaphore_discard(dmix);
- if (--fail_sem_loop <= 0)
- goto _err_nosem;
- continue;
- }
- break;
- }
-
- first_instance = ret = snd_pcm_direct_shm_create_or_connect(dmix);
- if (ret < 0) {
- SNDERR("unable to create IPC shm instance");
- goto _err;
- }
-
pcm->ops = &snd_pcm_dmix_ops;
pcm->fast_ops = &snd_pcm_dmix_fast_ops;
pcm->private_data = dmix;
snd_pcm_direct_t *dshare = NULL;
int ret, first_instance;
unsigned int chn;
- int fail_sem_loop = 10;
assert(pcmp);
return -EINVAL;
}
- dshare = calloc(1, sizeof(snd_pcm_direct_t));
- if (!dshare) {
- ret = -ENOMEM;
- goto _err_nosem;
- }
-
- ret = snd_pcm_direct_parse_bindings(dshare, params, opts->bindings);
- if (ret < 0)
- goto _err_nosem;
-
- dshare->ipc_key = opts->ipc_key;
- dshare->ipc_perm = opts->ipc_perm;
- dshare->ipc_gid = opts->ipc_gid;
- dshare->tstamp_type = opts->tstamp_type;
- dshare->semid = -1;
- dshare->shmid = -1;
- dshare->shmptr = (void *) -1;
-
- ret = snd_pcm_new(&pcm, dshare->type = SND_PCM_TYPE_DSHARE, name, stream, mode);
+ ret = _snd_pcm_direct_new(pcmp, &dshare, SND_PCM_TYPE_DSHARE, name, opts, params, stream, mode);
if (ret < 0)
- goto _err_nosem;
-
- while (1) {
- ret = snd_pcm_direct_semaphore_create_or_connect(dshare);
- if (ret < 0) {
- SNDERR("unable to create IPC semaphore");
- goto _err_nosem;
- }
-
- ret = snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT);
- if (ret < 0) {
- snd_pcm_direct_semaphore_discard(dshare);
- if (--fail_sem_loop <= 0)
- goto _err_nosem;
- continue;
- }
- break;
- }
-
- first_instance = ret = snd_pcm_direct_shm_create_or_connect(dshare);
- if (ret < 0) {
- SNDERR("unable to create IPC shm instance");
- goto _err;
- }
+ return ret;
+ first_instance = ret;
if (!dshare->bindings) {
pcm->ops = &snd_pcm_dshare_dummy_ops;
{
snd_pcm_t *pcm = NULL, *spcm = NULL;
snd_pcm_direct_t *dsnoop = NULL;
- int ret, first_instance, fail_sem_loop = 10;
+ int ret, first_instance;
assert(pcmp);
return -EINVAL;
}
- dsnoop = calloc(1, sizeof(snd_pcm_direct_t));
- if (!dsnoop) {
- ret = -ENOMEM;
- goto _err_nosem;
- }
-
- ret = snd_pcm_direct_parse_bindings(dsnoop, params, opts->bindings);
+ ret = _snd_pcm_direct_new(pcmp, &dsnoop, SND_PCM_TYPE_DSNOOP, name, opts, params, stream, mode);
if (ret < 0)
- goto _err_nosem;
-
- dsnoop->ipc_key = opts->ipc_key;
- dsnoop->ipc_perm = opts->ipc_perm;
- dsnoop->ipc_gid = opts->ipc_gid;
- dsnoop->tstamp_type = opts->tstamp_type;
- dsnoop->semid = -1;
- dsnoop->shmid = -1;
-
- ret = snd_pcm_new(&pcm, dsnoop->type = SND_PCM_TYPE_DSNOOP, name, stream, mode);
- if (ret < 0)
- goto _err_nosem;
+ return ret;
+ first_instance = ret;
- while (1) {
- ret = snd_pcm_direct_semaphore_create_or_connect(dsnoop);
- if (ret < 0) {
- SNDERR("unable to create IPC semaphore");
- goto _err_nosem;
- }
-
- ret = snd_pcm_direct_semaphore_down(dsnoop, DIRECT_IPC_SEM_CLIENT);
- if (ret < 0) {
- snd_pcm_direct_semaphore_discard(dsnoop);
- if (--fail_sem_loop <= 0)
- goto _err_nosem;
- continue;
- }
- break;
- }
-
- first_instance = ret = snd_pcm_direct_shm_create_or_connect(dsnoop);
- if (ret < 0) {
- SNDERR("unable to create IPC shm instance");
- goto _err;
- }
-
pcm->ops = &snd_pcm_dsnoop_ops;
pcm->fast_ops = &snd_pcm_dsnoop_fast_ops;
pcm->private_data = dsnoop;