mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-05 13:30:00 -05:00
Direct plugins update:
- moved more common code to pcm_direct.c - added missing initialization of some variables in hw_params
This commit is contained in:
parent
c0e493eb5a
commit
95418afc67
5 changed files with 244 additions and 585 deletions
|
|
@ -146,180 +146,6 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm)
|
|||
* plugin implementation
|
||||
*/
|
||||
|
||||
static int snd_pcm_dsnoop_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* value is cached for us in pcm->mode (SND_PCM_NONBLOCK flag) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||
{
|
||||
snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
return snd_timer_async(dsnoop->timer, sig, pid);
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
unsigned short events;
|
||||
static snd_timer_read_t rbuf[5]; /* can be overwriten by multiple plugins, we don't need the value */
|
||||
|
||||
assert(pfds && nfds == 1 && revents);
|
||||
events = pfds[0].revents;
|
||||
if (events & POLLIN) {
|
||||
events |= POLLOUT;
|
||||
events &= ~POLLIN;
|
||||
/* empty the timer read queue */
|
||||
while (snd_timer_read(dsnoop->timer, &rbuf, sizeof(rbuf)) == sizeof(rbuf)) ;
|
||||
}
|
||||
*revents = events;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||
{
|
||||
// snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->stream = pcm->stream;
|
||||
info->card = -1;
|
||||
/* FIXME: fill this with something more useful: we know the hardware name */
|
||||
if (pcm->name) {
|
||||
strncpy(info->id, pcm->name, sizeof(info->id));
|
||||
strncpy(info->name, pcm->name, sizeof(info->name));
|
||||
strncpy(info->subname, pcm->name, sizeof(info->subname));
|
||||
}
|
||||
info->subdevices_count = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline snd_mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
|
||||
snd_pcm_hw_param_t var)
|
||||
{
|
||||
return ¶ms->masks[var - SND_PCM_HW_PARAM_FIRST_MASK];
|
||||
}
|
||||
|
||||
static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
|
||||
snd_pcm_hw_param_t var)
|
||||
{
|
||||
return ¶ms->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
|
||||
}
|
||||
|
||||
static int hw_param_interval_refine_one(snd_pcm_hw_params_t *params,
|
||||
snd_pcm_hw_param_t var,
|
||||
snd_pcm_hw_params_t *src)
|
||||
{
|
||||
snd_interval_t *i;
|
||||
|
||||
if (!(params->rmask & (1<<var))) /* nothing to do? */
|
||||
return 0;
|
||||
i = hw_param_interval(params, var);
|
||||
if (snd_interval_empty(i)) {
|
||||
SNDERR("dsnoop interval %i empty?", (int)var);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snd_interval_refine(i, hw_param_interval(src, var)))
|
||||
params->cmask |= 1<<var;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef REFINE_DEBUG
|
||||
|
||||
static int snd_pcm_dsnoop_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
snd_pcm_hw_params_t *hw_params = &dsnoop->shmptr->hw_params;
|
||||
static snd_mask_t access = { .bits = {
|
||||
(1<<SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) |
|
||||
(1<<SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) |
|
||||
(1<<SNDRV_PCM_ACCESS_RW_INTERLEAVED) |
|
||||
(1<<SNDRV_PCM_ACCESS_RW_NONINTERLEAVED),
|
||||
0, 0, 0 } };
|
||||
int err;
|
||||
|
||||
#ifdef REFINE_DEBUG
|
||||
snd_output_t *log;
|
||||
snd_output_stdio_attach(&log, stderr, 0);
|
||||
snd_output_puts(log, "DMIX REFINE (begin):\n");
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
#endif
|
||||
if (params->rmask & (1<<SND_PCM_HW_PARAM_ACCESS)) {
|
||||
if (snd_mask_empty(hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS))) {
|
||||
SNDERR("dsnoop access mask empty?");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snd_mask_refine(hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS), &access))
|
||||
params->cmask |= 1<<SND_PCM_HW_PARAM_ACCESS;
|
||||
}
|
||||
if (params->rmask & (1<<SND_PCM_HW_PARAM_FORMAT)) {
|
||||
if (snd_mask_empty(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT))) {
|
||||
SNDERR("dsnoop format mask empty?");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snd_mask_refine_set(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT),
|
||||
snd_mask_value(hw_param_mask(hw_params, SND_PCM_HW_PARAM_FORMAT))))
|
||||
params->cmask |= 1<<SND_PCM_HW_PARAM_FORMAT;
|
||||
}
|
||||
//snd_mask_none(hw_param_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
|
||||
if (params->rmask & (1<<SND_PCM_HW_PARAM_CHANNELS)) {
|
||||
if (snd_interval_empty(hw_param_interval(params, SND_PCM_HW_PARAM_CHANNELS))) {
|
||||
SNDERR("dsnoop channels mask empty?");
|
||||
return -EINVAL;
|
||||
}
|
||||
err = snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_CHANNELS), dsnoop->channels);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_RATE, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_TIME, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_SIZE, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_TIME, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIODS, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef REFINE_DEBUG
|
||||
snd_output_puts(log, "DMIX REFINE (end):\n");
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
snd_output_close(log);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_hw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t * params ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* values are cached in the pcm structure */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* values are cached in the pcm structure */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t * params ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* values are cached in the pcm structure */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
|
||||
{
|
||||
return snd_pcm_channel_info_shm(pcm, info, -1);
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||
{
|
||||
snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
|
|
@ -514,16 +340,6 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_writen(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_dsnoop_close(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
|
|
@ -593,18 +409,18 @@ static void snd_pcm_dsnoop_dump(snd_pcm_t *pcm, snd_output_t *out)
|
|||
|
||||
static snd_pcm_ops_t snd_pcm_dsnoop_ops = {
|
||||
.close = snd_pcm_dsnoop_close,
|
||||
.info = snd_pcm_dsnoop_info,
|
||||
.hw_refine = snd_pcm_dsnoop_hw_refine,
|
||||
.hw_params = snd_pcm_dsnoop_hw_params,
|
||||
.hw_free = snd_pcm_dsnoop_hw_free,
|
||||
.sw_params = snd_pcm_dsnoop_sw_params,
|
||||
.channel_info = snd_pcm_dsnoop_channel_info,
|
||||
.info = snd_pcm_direct_info,
|
||||
.hw_refine = snd_pcm_direct_hw_refine,
|
||||
.hw_params = snd_pcm_direct_hw_params,
|
||||
.hw_free = snd_pcm_direct_hw_free,
|
||||
.sw_params = snd_pcm_direct_sw_params,
|
||||
.channel_info = snd_pcm_direct_channel_info,
|
||||
.dump = snd_pcm_dsnoop_dump,
|
||||
.nonblock = snd_pcm_dsnoop_nonblock,
|
||||
.async = snd_pcm_dsnoop_async,
|
||||
.poll_revents = snd_pcm_dsnoop_poll_revents,
|
||||
.mmap = snd_pcm_dsnoop_mmap,
|
||||
.munmap = snd_pcm_dsnoop_munmap,
|
||||
.nonblock = snd_pcm_direct_nonblock,
|
||||
.async = snd_pcm_direct_async,
|
||||
.poll_revents = snd_pcm_direct_poll_revents,
|
||||
.mmap = snd_pcm_direct_mmap,
|
||||
.munmap = snd_pcm_direct_munmap,
|
||||
};
|
||||
|
||||
static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
|
||||
|
|
@ -754,6 +570,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
|||
spcm->channels = dsnoop->shmptr->s.channels;
|
||||
spcm->format = dsnoop->shmptr->s.format;
|
||||
spcm->boundary = dsnoop->shmptr->s.boundary;
|
||||
spcm->info = dsnoop->shmptr->s.info;
|
||||
ret = snd_pcm_mmap(spcm);
|
||||
if (ret < 0) {
|
||||
SNDERR("unable to mmap channels");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue