From e77cbd919d9e9dccc572a8fbeb4f9632238aed96 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Tue, 9 May 2000 10:46:43 +0000 Subject: [PATCH] Completed pcm_update implementation --- include/pcm.h | 1 + src/pcm/pcm.c | 16 ++++++++++++++++ src/pcm/pcm_hw.c | 11 +++++++++++ src/pcm/pcm_local.h | 1 + src/pcm/pcm_mmap.c | 6 ++++-- src/pcm/pcm_plug.c | 18 ++++++++++++++++++ 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/pcm.h b/include/pcm.h index 6eb060b3..a3febb93 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -113,6 +113,7 @@ int snd_pcm_capture_flush(snd_pcm_t *handle); int snd_pcm_channel_flush(snd_pcm_t *handle, int channel); int snd_pcm_playback_pause(snd_pcm_t *handle, int enable); int snd_pcm_channel_pause(snd_pcm_t *handle, int channel, int enable); +int snd_pcm_channel_update(snd_pcm_t *handle, int channel); ssize_t snd_pcm_transfer_size(snd_pcm_t *handle, int channel); ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size); ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size); diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index aae4d02a..20f3a473 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -275,6 +275,22 @@ int snd_pcm_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t *status) return pcm->ops->channel_status(pcm, status); } +int snd_pcm_channel_update(snd_pcm_t *pcm, int channel) +{ + int err; + if (!pcm) + return -EFAULT; + if (channel < 0 || channel > 1) + return -EINVAL; + if (!pcm->chan[channel].open) + return -EBADFD; + err = pcm->ops->channel_update(pcm, channel); + if (err < 0) + return err; + snd_pcm_mmap_status_change(pcm, channel, -1); + return 0; +} + int snd_pcm_channel_prepare(snd_pcm_t *pcm, int channel) { int err; diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index edcbe444..293bed3a 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -139,6 +139,16 @@ static int snd_pcm_hw_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t * return 0; } +static int snd_pcm_hw_channel_update(snd_pcm_t *pcm, int channel) +{ + int fd; + snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private; + fd = hw->chan[channel].fd; + if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_UPDATE) < 0) + return -errno; + return 0; +} + static int snd_pcm_hw_channel_prepare(snd_pcm_t *pcm, int channel) { int fd; @@ -329,6 +339,7 @@ struct snd_pcm_ops snd_pcm_hw_ops = { channel_setup: snd_pcm_hw_channel_setup, voice_setup: snd_pcm_hw_voice_setup, channel_status: snd_pcm_hw_channel_status, + channel_update: snd_pcm_hw_channel_update, channel_prepare: snd_pcm_hw_channel_prepare, channel_go: snd_pcm_hw_channel_go, sync_go: snd_pcm_hw_sync_go, diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 4bd07ae7..5f3ce7b4 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -33,6 +33,7 @@ struct snd_pcm_ops { int (*voice_setup)(snd_pcm_t *pcm, int channel, snd_pcm_voice_setup_t *setup); int (*channel_status)(snd_pcm_t *pcm, snd_pcm_channel_status_t *status); int (*channel_prepare)(snd_pcm_t *pcm, int channel); + int (*channel_update)(snd_pcm_t *pcm, int channel); int (*channel_go)(snd_pcm_t *pcm, int channel); int (*sync_go)(snd_pcm_t *pcm, snd_pcm_sync_t *sync); int (*channel_drain)(snd_pcm_t *pcm, int channel); diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c index 5db9fb81..f8ad2ebb 100644 --- a/src/pcm/pcm_mmap.c +++ b/src/pcm/pcm_mmap.c @@ -131,7 +131,6 @@ static ssize_t snd_pcm_mmap_playback_bytes_used(snd_pcm_t *pcm) { struct snd_pcm_chan *chan; ssize_t bytes_used; - // snd_pcm_update_pos(pcm, SND_PCM_CHANNEL_PLAYBACK); chan = &pcm->chan[SND_PCM_CHANNEL_PLAYBACK]; bytes_used = chan->mmap_control->pos_data - chan->mmap_control->pos_io; if (bytes_used < (ssize_t)(chan->setup.buffer_size - chan->setup.pos_boundary)) @@ -143,7 +142,6 @@ static size_t snd_pcm_mmap_capture_bytes_used(snd_pcm_t *pcm) { struct snd_pcm_chan *chan; ssize_t bytes_used; - // snd_pcm_update_pos(pcm, SND_PCM_CHANNEL_CAPTURE); chan = &pcm->chan[SND_PCM_CHANNEL_CAPTURE]; bytes_used = chan->mmap_control->pos_io - chan->mmap_control->pos_data; if (bytes_used < 0) @@ -319,6 +317,8 @@ static ssize_t snd_pcm_mmap_write1(snd_pcm_t *pcm, const void *data, size_t coun } } } + if (chan->mode & SND_PCM_NONBLOCK) + snd_pcm_channel_update(pcm, SND_PCM_CHANNEL_PLAYBACK); while (count > 0) { size_t bytes; int ready = snd_pcm_mmap_playback_ready(pcm); @@ -583,6 +583,8 @@ static ssize_t snd_pcm_mmap_read1(snd_pcm_t *pcm, void *data, size_t count, tran if (err < 0) return err; } + if (chan->mode & SND_PCM_NONBLOCK) + snd_pcm_channel_update(pcm, SND_PCM_CHANNEL_CAPTURE); while (count > 0) { size_t bytes; int ready = snd_pcm_mmap_capture_ready(pcm); diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index 43cc1edd..953e06dc 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -507,6 +507,23 @@ static int snd_pcm_plug_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t return 0; } +static int snd_pcm_plug_channel_update(snd_pcm_t *pcm, int channel) +{ + snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private; + int err; + err = snd_pcm_channel_update(plug->slave, channel); + if (err < 0) + return err; + if (snd_pcm_plug_direct(pcm, channel)) + return 0; +#if 0 + /* To think more about that */ + if ((err = snd_pcm_plug_action(pcm, channel, UPDATE, 0))<0) + return err; +#endif + return 0; +} + static int snd_pcm_plug_channel_prepare(snd_pcm_t *pcm, int channel) { snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private; @@ -769,6 +786,7 @@ struct snd_pcm_ops snd_pcm_plug_ops = { channel_setup: snd_pcm_plug_channel_setup, voice_setup: snd_pcm_plug_voice_setup, channel_status: snd_pcm_plug_channel_status, + channel_update: snd_pcm_plug_channel_update, channel_prepare: snd_pcm_plug_channel_prepare, channel_go: snd_pcm_plug_channel_go, sync_go: snd_pcm_plug_sync_go, -- 2.47.1