aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pcm/pcm_direct.c195
-rw-r--r--src/pcm/pcm_direct.h13
-rw-r--r--src/pcm/pcm_dmix.c207
-rw-r--r--src/pcm/pcm_dshare.c207
-rw-r--r--src/pcm/pcm_dsnoop.c207
5 files changed, 244 insertions, 585 deletions
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 5866883f..b2510c3d 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -375,6 +375,199 @@ int snd_pcm_direct_client_discard(snd_pcm_direct_t *dmix)
}
/*
+ * plugin helpers
+ */
+
+int snd_pcm_direct_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;
+}
+
+int snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid)
+{
+ snd_pcm_direct_t *dmix = pcm->private_data;
+ return snd_timer_async(dmix->timer, sig, pid);
+}
+
+int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+ snd_pcm_direct_t *dmix = 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(dmix->timer, &rbuf, sizeof(rbuf)) == sizeof(rbuf)) ;
+ }
+ *revents = events;
+ return 0;
+}
+
+int snd_pcm_direct_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
+{
+ // snd_pcm_direct_t *dmix = 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 &params->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 &params->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("dshare 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
+
+int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+ snd_pcm_direct_t *dshare = pcm->private_data;
+ snd_pcm_hw_params_t *hw_params = &dshare->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("dshare 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("dshare 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("dshare channels mask empty?");
+ return -EINVAL;
+ }
+ err = snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_CHANNELS), dshare->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;
+}
+
+int snd_pcm_direct_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
+{
+ snd_pcm_direct_t *dmix = pcm->private_data;
+
+ params->info = dmix->shmptr->s.info;
+ params->rate_num = dmix->shmptr->s.rate;
+ params->rate_den = 1;
+ params->fifo_size = 0;
+ params->msbits = dmix->shmptr->s.msbits;
+ return 0;
+}
+
+int snd_pcm_direct_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ /* values are cached in the pcm structure */
+ return 0;
+}
+
+int snd_pcm_direct_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;
+}
+
+int snd_pcm_direct_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
+{
+ return snd_pcm_channel_info_shm(pcm, info, -1);
+}
+
+int snd_pcm_direct_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int snd_pcm_direct_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/*
* this function initializes hardware and starts playback operation with
* no stop threshold (it operates all time without xrun checking)
* also, the driver silences the unused ring buffer areas for us
@@ -578,6 +771,8 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
dmix->shmptr->s.rate = spcm->rate;
dmix->shmptr->s.format = spcm->format;
dmix->shmptr->s.boundary = spcm->boundary;
+ dmix->shmptr->s.info = spcm->info;
+ dmix->shmptr->s.msbits = spcm->msbits;
spcm->donot_close = 1;
return 0;
diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h
index bb60b9fc..48f18998 100644
--- a/src/pcm/pcm_direct.h
+++ b/src/pcm/pcm_direct.h
@@ -64,6 +64,8 @@ typedef struct {
unsigned int sample_bits;
unsigned int rate;
snd_pcm_format_t format;
+ unsigned int info;
+ unsigned int msbits;
} s;
union {
struct {
@@ -128,6 +130,17 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix);
int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm);
int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, snd_config_t *cfg);
+int snd_pcm_direct_nonblock(snd_pcm_t *pcm, int nonblock);
+int snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid);
+int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_pcm_direct_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
+int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_direct_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params);
+int snd_pcm_direct_hw_free(snd_pcm_t *pcm);
+int snd_pcm_direct_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params);
+int snd_pcm_direct_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
+int snd_pcm_direct_mmap(snd_pcm_t *pcm);
+int snd_pcm_direct_munmap(snd_pcm_t *pcm);
int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
index c975aec2..f57b3ab3 100644
--- a/src/pcm/pcm_dmix.c
+++ b/src/pcm/pcm_dmix.c
@@ -376,180 +376,6 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm)
* plugin implementation
*/
-static int snd_pcm_dmix_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_dmix_async(snd_pcm_t *pcm, int sig, pid_t pid)
-{
- snd_pcm_direct_t *dmix = pcm->private_data;
- return snd_timer_async(dmix->timer, sig, pid);
-}
-
-static int snd_pcm_dmix_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
-{
- snd_pcm_direct_t *dmix = 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(dmix->timer, &rbuf, sizeof(rbuf)) == sizeof(rbuf)) ;
- }
- *revents = events;
- return 0;
-}
-
-static int snd_pcm_dmix_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
-{
- // snd_pcm_direct_t *dmix = 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 &params->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 &params->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("dmix 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_dmix_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
- snd_pcm_direct_t *dmix = pcm->private_data;
- snd_pcm_hw_params_t *hw_params = &dmix->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("dmix 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("dmix 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("dmix channels mask empty?");
- return -EINVAL;
- }
- err = snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_CHANNELS), dmix->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_dmix_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_dmix_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
- /* values are cached in the pcm structure */
- return 0;
-}
-
-static int snd_pcm_dmix_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_dmix_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_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
snd_pcm_direct_t *dmix = pcm->private_data;
@@ -752,16 +578,6 @@ static snd_pcm_sframes_t snd_pcm_dmix_readn(snd_pcm_t *pcm ATTRIBUTE_UNUSED, voi
return -ENODEV;
}
-static int snd_pcm_dmix_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-static int snd_pcm_dmix_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
static int snd_pcm_dmix_close(snd_pcm_t *pcm)
{
snd_pcm_direct_t *dmix = pcm->private_data;
@@ -835,18 +651,18 @@ static void snd_pcm_dmix_dump(snd_pcm_t *pcm, snd_output_t *out)
static snd_pcm_ops_t snd_pcm_dmix_ops = {
.close = snd_pcm_dmix_close,
- .info = snd_pcm_dmix_info,
- .hw_refine = snd_pcm_dmix_hw_refine,
- .hw_params = snd_pcm_dmix_hw_params,
- .hw_free = snd_pcm_dmix_hw_free,
- .sw_params = snd_pcm_dmix_sw_params,
- .channel_info = snd_pcm_dmix_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_dmix_dump,
- .nonblock = snd_pcm_dmix_nonblock,
- .async = snd_pcm_dmix_async,
- .poll_revents = snd_pcm_dmix_poll_revents,
- .mmap = snd_pcm_dmix_mmap,
- .munmap = snd_pcm_dmix_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_dmix_fast_ops = {
@@ -999,6 +815,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
spcm->channels = dmix->shmptr->s.channels;
spcm->format = dmix->shmptr->s.format;
spcm->boundary = dmix->shmptr->s.boundary;
+ spcm->info = dmix->shmptr->s.info;
ret = snd_pcm_mmap(spcm);
if (ret < 0) {
SNDERR("unable to mmap channels");
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
index 8d28ed58..bcb051f7 100644
--- a/src/pcm/pcm_dshare.c
+++ b/src/pcm/pcm_dshare.c
@@ -163,180 +163,6 @@ static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm)
* plugin implementation
*/
-static int snd_pcm_dshare_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_dshare_async(snd_pcm_t *pcm, int sig, pid_t pid)
-{
- snd_pcm_direct_t *dshare = pcm->private_data;
- return snd_timer_async(dshare->timer, sig, pid);
-}
-
-static int snd_pcm_dshare_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
-{
- snd_pcm_direct_t *dshare = 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(dshare->timer, &rbuf, sizeof(rbuf)) == sizeof(rbuf)) ;
- }
- *revents = events;
- return 0;
-}
-
-static int snd_pcm_dshare_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
-{
- // snd_pcm_direct_t *dshare = 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 &params->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 &params->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("dshare 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_dshare_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
- snd_pcm_direct_t *dshare = pcm->private_data;
- snd_pcm_hw_params_t *hw_params = &dshare->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("dshare 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("dshare 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("dshare channels mask empty?");
- return -EINVAL;
- }
- err = snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_CHANNELS), dshare->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_dshare_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_dshare_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
- /* values are cached in the pcm structure */
- return 0;
-}
-
-static int snd_pcm_dshare_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_dshare_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_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
snd_pcm_direct_t *dshare = pcm->private_data;
@@ -541,16 +367,6 @@ static snd_pcm_sframes_t snd_pcm_dshare_readn(snd_pcm_t *pcm ATTRIBUTE_UNUSED, v
return -ENODEV;
}
-static int snd_pcm_dshare_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-static int snd_pcm_dshare_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
static int snd_pcm_dshare_close(snd_pcm_t *pcm)
{
snd_pcm_direct_t *dshare = pcm->private_data;
@@ -625,18 +441,18 @@ static void snd_pcm_dshare_dump(snd_pcm_t *pcm, snd_output_t *out)
static snd_pcm_ops_t snd_pcm_dshare_ops = {
.close = snd_pcm_dshare_close,
- .info = snd_pcm_dshare_info,
- .hw_refine = snd_pcm_dshare_hw_refine,
- .hw_params = snd_pcm_dshare_hw_params,
- .hw_free = snd_pcm_dshare_hw_free,
- .sw_params = snd_pcm_dshare_sw_params,
- .channel_info = snd_pcm_dshare_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_dshare_dump,
- .nonblock = snd_pcm_dshare_nonblock,
- .async = snd_pcm_dshare_async,
- .poll_revents = snd_pcm_dshare_poll_revents,
- .mmap = snd_pcm_dshare_mmap,
- .munmap = snd_pcm_dshare_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_dshare_fast_ops = {
@@ -794,6 +610,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
spcm->channels = dshare->shmptr->s.channels;
spcm->format = dshare->shmptr->s.format;
spcm->boundary = dshare->shmptr->s.boundary;
+ spcm->info = dshare->shmptr->s.info;
ret = snd_pcm_mmap(spcm);
if (ret < 0) {
SNDERR("unable to mmap channels");
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
index d163095b..28baa4d2 100644
--- a/src/pcm/pcm_dsnoop.c
+++ b/src/pcm/pcm_dsnoop.c
@@ -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 &params->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 &params->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");