mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-12-19 08:57:08 -05:00
Added slowptr options to direct plugins
This commit is contained in:
parent
852b0c6129
commit
eeb5d6f0ac
4 changed files with 73 additions and 6 deletions
|
|
@ -99,6 +99,7 @@ struct snd_pcm_direct {
|
||||||
pid_t server_pid;
|
pid_t server_pid;
|
||||||
snd_timer_t *timer; /* timer used as poll_fd */
|
snd_timer_t *timer; /* timer used as poll_fd */
|
||||||
int interleaved; /* we have interleaved buffer */
|
int interleaved; /* we have interleaved buffer */
|
||||||
|
int slowptr; /* use slow but more precise ptr updates */
|
||||||
unsigned int channels; /* client's channels */
|
unsigned int channels; /* client's channels */
|
||||||
unsigned int *bindings;
|
unsigned int *bindings;
|
||||||
union {
|
union {
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,8 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (dmix->slowptr)
|
||||||
|
snd_pcm_hwsync(dmix->spcm);
|
||||||
old_slave_hw_ptr = dmix->slave_hw_ptr;
|
old_slave_hw_ptr = dmix->slave_hw_ptr;
|
||||||
slave_hw_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
|
slave_hw_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
|
||||||
diff = slave_hw_ptr - old_slave_hw_ptr;
|
diff = slave_hw_ptr - old_slave_hw_ptr;
|
||||||
|
|
@ -759,6 +761,8 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
|
||||||
* \param ipc_key IPC key for semaphore and shared memory
|
* \param ipc_key IPC key for semaphore and shared memory
|
||||||
* \param ipc_perm IPC permissions for semaphore and shared memory
|
* \param ipc_perm IPC permissions for semaphore and shared memory
|
||||||
* \param params Parameters for slave
|
* \param params Parameters for slave
|
||||||
|
* \param bindings Channel bindings
|
||||||
|
* \param slowptr Slow but more precise pointer updates
|
||||||
* \param root Configuration root
|
* \param root Configuration root
|
||||||
* \param sconf Slave configuration
|
* \param sconf Slave configuration
|
||||||
* \param stream PCM Direction (stream)
|
* \param stream PCM Direction (stream)
|
||||||
|
|
@ -772,6 +776,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||||
key_t ipc_key, mode_t ipc_perm,
|
key_t ipc_key, mode_t ipc_perm,
|
||||||
struct slave_params *params,
|
struct slave_params *params,
|
||||||
snd_config_t *bindings,
|
snd_config_t *bindings,
|
||||||
|
int slowptr,
|
||||||
snd_config_t *root, snd_config_t *sconf,
|
snd_config_t *root, snd_config_t *sconf,
|
||||||
snd_pcm_stream_t stream, int mode)
|
snd_pcm_stream_t stream, int mode)
|
||||||
{
|
{
|
||||||
|
|
@ -833,6 +838,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->fast_ops = &snd_pcm_dmix_fast_ops;
|
pcm->fast_ops = &snd_pcm_dmix_fast_ops;
|
||||||
pcm->private_data = dmix;
|
pcm->private_data = dmix;
|
||||||
dmix->state = SND_PCM_STATE_OPEN;
|
dmix->state = SND_PCM_STATE_OPEN;
|
||||||
|
dmix->slowptr = slowptr;
|
||||||
|
|
||||||
if (first_instance) {
|
if (first_instance) {
|
||||||
ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
|
ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
|
||||||
|
|
@ -1082,7 +1088,7 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_config_iterator_t i, next;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *slave = NULL, *bindings = NULL, *sconf;
|
snd_config_t *slave = NULL, *bindings = NULL, *sconf;
|
||||||
struct slave_params params;
|
struct slave_params params;
|
||||||
int bsize, psize, ipc_key_add_uid = 0;
|
int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
|
||||||
key_t ipc_key = 0;
|
key_t ipc_key = 0;
|
||||||
mode_t ipc_perm = 0600;
|
mode_t ipc_perm = 0600;
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -1142,6 +1148,22 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||||
bindings = n;
|
bindings = n;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(id, "slowptr") == 0) {
|
||||||
|
char *tmp;
|
||||||
|
err = snd_config_get_ascii(n, &tmp);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("The field slowptr must be a boolean type");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = snd_config_get_bool_ascii(tmp);
|
||||||
|
free(tmp);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("The field slowptr must be a boolean type");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
slowptr = err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
SNDERR("Unknown field %s", id);
|
SNDERR("Unknown field %s", id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -1179,7 +1201,7 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||||
params.period_size = psize;
|
params.period_size = psize;
|
||||||
params.buffer_size = bsize;
|
params.buffer_size = bsize;
|
||||||
|
|
||||||
err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, ¶ms, bindings, root, sconf, stream, mode);
|
err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, ¶ms, bindings, slowptr, root, sconf, stream, mode);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
snd_config_delete(sconf);
|
snd_config_delete(sconf);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,8 @@ static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (dshare->slowptr)
|
||||||
|
snd_pcm_hwsync(dshare->spcm);
|
||||||
old_slave_hw_ptr = dshare->slave_hw_ptr;
|
old_slave_hw_ptr = dshare->slave_hw_ptr;
|
||||||
slave_hw_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr;
|
slave_hw_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr;
|
||||||
diff = slave_hw_ptr - old_slave_hw_ptr;
|
diff = slave_hw_ptr - old_slave_hw_ptr;
|
||||||
|
|
@ -509,6 +511,8 @@ static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
|
||||||
* \param ipc_key IPC key for semaphore and shared memory
|
* \param ipc_key IPC key for semaphore and shared memory
|
||||||
* \param ipc_mode IPC permissions for semaphore and shared memory
|
* \param ipc_mode IPC permissions for semaphore and shared memory
|
||||||
* \param params Parameters for slave
|
* \param params Parameters for slave
|
||||||
|
* \param bindings Channel bindings
|
||||||
|
* \param slowptr Slow but more precise pointer updates
|
||||||
* \param root Configuration root
|
* \param root Configuration root
|
||||||
* \param sconf Slave configuration
|
* \param sconf Slave configuration
|
||||||
* \param stream PCM Direction (stream)
|
* \param stream PCM Direction (stream)
|
||||||
|
|
@ -522,6 +526,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||||
key_t ipc_key, mode_t ipc_perm,
|
key_t ipc_key, mode_t ipc_perm,
|
||||||
struct slave_params *params,
|
struct slave_params *params,
|
||||||
snd_config_t *bindings,
|
snd_config_t *bindings,
|
||||||
|
int slowptr,
|
||||||
snd_config_t *root, snd_config_t *sconf,
|
snd_config_t *root, snd_config_t *sconf,
|
||||||
snd_pcm_stream_t stream, int mode)
|
snd_pcm_stream_t stream, int mode)
|
||||||
{
|
{
|
||||||
|
|
@ -590,6 +595,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->fast_ops = &snd_pcm_dshare_fast_ops;
|
pcm->fast_ops = &snd_pcm_dshare_fast_ops;
|
||||||
pcm->private_data = dshare;
|
pcm->private_data = dshare;
|
||||||
dshare->state = SND_PCM_STATE_OPEN;
|
dshare->state = SND_PCM_STATE_OPEN;
|
||||||
|
dshare->slowptr = slowptr;
|
||||||
|
|
||||||
if (first_instance) {
|
if (first_instance) {
|
||||||
ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
|
ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
|
||||||
|
|
@ -771,7 +777,7 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_config_iterator_t i, next;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *slave = NULL, *bindings = NULL, *sconf;
|
snd_config_t *slave = NULL, *bindings = NULL, *sconf;
|
||||||
struct slave_params params;
|
struct slave_params params;
|
||||||
int bsize, psize, ipc_key_add_uid = 0;
|
int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
|
||||||
key_t ipc_key = 0;
|
key_t ipc_key = 0;
|
||||||
mode_t ipc_perm = 0600;
|
mode_t ipc_perm = 0600;
|
||||||
|
|
||||||
|
|
@ -832,6 +838,22 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||||
bindings = n;
|
bindings = n;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(id, "slowptr") == 0) {
|
||||||
|
char *tmp;
|
||||||
|
err = snd_config_get_ascii(n, &tmp);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("The field slowptr must be a boolean type");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = snd_config_get_bool_ascii(tmp);
|
||||||
|
free(tmp);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("The field slowptr must be a boolean type");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
slowptr = err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
SNDERR("Unknown field %s", id);
|
SNDERR("Unknown field %s", id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -867,7 +889,7 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||||
|
|
||||||
params.period_size = psize;
|
params.period_size = psize;
|
||||||
params.buffer_size = bsize;
|
params.buffer_size = bsize;
|
||||||
err = snd_pcm_dshare_open(pcmp, name, ipc_key, ipc_perm, ¶ms, bindings, root, sconf, stream, mode);
|
err = snd_pcm_dshare_open(pcmp, name, ipc_key, ipc_perm, ¶ms, bindings, slowptr, root, sconf, stream, mode);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
snd_config_delete(sconf);
|
snd_config_delete(sconf);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,8 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (dsnoop->slowptr)
|
||||||
|
snd_pcm_hwsync(dsnoop->spcm);
|
||||||
old_slave_hw_ptr = dsnoop->slave_hw_ptr;
|
old_slave_hw_ptr = dsnoop->slave_hw_ptr;
|
||||||
slave_hw_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr;
|
slave_hw_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr;
|
||||||
diff = slave_hw_ptr - old_slave_hw_ptr;
|
diff = slave_hw_ptr - old_slave_hw_ptr;
|
||||||
|
|
@ -477,6 +479,8 @@ static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
|
||||||
* \param ipc_key IPC key for semaphore and shared memory
|
* \param ipc_key IPC key for semaphore and shared memory
|
||||||
* \param ipc_perm IPC permissions for semaphore and shared memory
|
* \param ipc_perm IPC permissions for semaphore and shared memory
|
||||||
* \param params Parameters for slave
|
* \param params Parameters for slave
|
||||||
|
* \param bindings Channel bindings
|
||||||
|
* \param slowptr Slow but more precise pointer updates
|
||||||
* \param root Configuration root
|
* \param root Configuration root
|
||||||
* \param sconf Slave configuration
|
* \param sconf Slave configuration
|
||||||
* \param stream PCM Direction (stream)
|
* \param stream PCM Direction (stream)
|
||||||
|
|
@ -490,6 +494,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||||
key_t ipc_key, mode_t ipc_perm,
|
key_t ipc_key, mode_t ipc_perm,
|
||||||
struct slave_params *params,
|
struct slave_params *params,
|
||||||
snd_config_t *bindings,
|
snd_config_t *bindings,
|
||||||
|
int slowptr,
|
||||||
snd_config_t *root, snd_config_t *sconf,
|
snd_config_t *root, snd_config_t *sconf,
|
||||||
snd_pcm_stream_t stream, int mode)
|
snd_pcm_stream_t stream, int mode)
|
||||||
{
|
{
|
||||||
|
|
@ -550,6 +555,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->fast_ops = &snd_pcm_dsnoop_fast_ops;
|
pcm->fast_ops = &snd_pcm_dsnoop_fast_ops;
|
||||||
pcm->private_data = dsnoop;
|
pcm->private_data = dsnoop;
|
||||||
dsnoop->state = SND_PCM_STATE_OPEN;
|
dsnoop->state = SND_PCM_STATE_OPEN;
|
||||||
|
dsnoop->slowptr = slowptr;
|
||||||
|
|
||||||
if (first_instance) {
|
if (first_instance) {
|
||||||
ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
|
ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
|
||||||
|
|
@ -721,7 +727,7 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_config_iterator_t i, next;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *slave = NULL, *bindings = NULL, *sconf;
|
snd_config_t *slave = NULL, *bindings = NULL, *sconf;
|
||||||
struct slave_params params;
|
struct slave_params params;
|
||||||
int bsize, psize, ipc_key_add_uid = 0;
|
int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
|
||||||
key_t ipc_key = 0;
|
key_t ipc_key = 0;
|
||||||
mode_t ipc_perm = 0600;
|
mode_t ipc_perm = 0600;
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -782,6 +788,22 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||||
bindings = n;
|
bindings = n;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(id, "slowptr") == 0) {
|
||||||
|
char *tmp;
|
||||||
|
err = snd_config_get_ascii(n, &tmp);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("The field slowptr must be a boolean type");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = snd_config_get_bool_ascii(tmp);
|
||||||
|
free(tmp);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("The field slowptr must be a boolean type");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
slowptr = err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
SNDERR("Unknown field %s", id);
|
SNDERR("Unknown field %s", id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -825,7 +847,7 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||||
|
|
||||||
params.period_size = psize;
|
params.period_size = psize;
|
||||||
params.buffer_size = bsize;
|
params.buffer_size = bsize;
|
||||||
err = snd_pcm_dsnoop_open(pcmp, name, ipc_key, ipc_perm, ¶ms, bindings, root, sconf, stream, mode);
|
err = snd_pcm_dsnoop_open(pcmp, name, ipc_key, ipc_perm, ¶ms, bindings, slowptr, root, sconf, stream, mode);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
snd_config_delete(sconf);
|
snd_config_delete(sconf);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue