OSDN Git Service

Completed pcm_update implementation
authorAbramo Bagnara <abramo@alsa-project.org>
Tue, 9 May 2000 10:46:43 +0000 (10:46 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Tue, 9 May 2000 10:46:43 +0000 (10:46 +0000)
include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_hw.c
src/pcm/pcm_local.h
src/pcm/pcm_mmap.c
src/pcm/pcm_plug.c

index 6eb060b..a3febb9 100644 (file)
@@ -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);
index aae4d02..20f3a47 100644 (file)
@@ -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;
index edcbe44..293bed3 100644 (file)
@@ -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,
index 4bd07ae..5f3ce7b 100644 (file)
@@ -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);
index 5db9fb8..f8ad2eb 100644 (file)
@@ -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);
index 43cc1ed..953e06d 100644 (file)
@@ -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,