]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Improved plugin code (simpler, faster and multithread ready)
authorAbramo Bagnara <abramo@alsa-project.org>
Tue, 27 Feb 2001 13:42:12 +0000 (13:42 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Tue, 27 Feb 2001 13:42:12 +0000 (13:42 +0000)
13 files changed:
src/pcm/pcm.c
src/pcm/pcm_adpcm.c
src/pcm/pcm_alaw.c
src/pcm/pcm_copy.c
src/pcm/pcm_linear.c
src/pcm/pcm_local.h
src/pcm/pcm_mmap.c
src/pcm/pcm_mulaw.c
src/pcm/pcm_multi.c
src/pcm/pcm_plugin.c
src/pcm/pcm_plugin.h
src/pcm/pcm_rate.c
src/pcm/pcm_route.c

index d868eef256dbd499af9f192a59a0657c5ca983ed..8a37d433dda179d84cf31346caba08c63d186f02 100644 (file)
@@ -1053,7 +1053,7 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_
                if (frames > (snd_pcm_uframes_t) avail)
                        frames = avail;
                assert(frames != 0);
-               err = func(pcm, areas, offset, frames, 0);
+               err = func(pcm, areas, offset, frames);
                if (err < 0)
                        break;
                assert((snd_pcm_uframes_t)err == frames);
@@ -1130,7 +1130,7 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
                if (frames > (snd_pcm_uframes_t) avail)
                        frames = avail;
                assert(frames != 0);
-               err = func(pcm, areas, offset, frames, 0);
+               err = func(pcm, areas, offset, frames);
                if (err < 0)
                        break;
                assert((snd_pcm_uframes_t)err == frames);
index cdd61a84e9832900a5a87548abc5a81e5389850a..6d033ccf5f188e54dd8f25463dec53a53bee9ec9 100644 (file)
@@ -452,74 +452,44 @@ static int snd_pcm_adpcm_init(snd_pcm_t *pcm)
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
-                                        const snd_pcm_channel_area_t *areas,
-                                        snd_pcm_uframes_t offset,
-                                        snd_pcm_uframes_t size,
-                                        snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
+                         const snd_pcm_channel_area_t *areas,
+                         snd_pcm_uframes_t offset,
+                         snd_pcm_uframes_t size,
+                         const snd_pcm_channel_area_t *slave_areas,
+                         snd_pcm_uframes_t slave_offset,
+                         snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_adpcm_t *adpcm = pcm->private_data;
-       snd_pcm_t *slave = adpcm->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
-               adpcm->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                           areas, offset, 
-                           pcm->channels, frames,
-                           adpcm->getput_idx, adpcm->states);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       adpcm->func(slave_areas, slave_offset,
+                   areas, offset, 
+                   pcm->channels, size,
+                   adpcm->getput_idx, adpcm->states);
+       *slave_sizep = size;
+       return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
-                                       const snd_pcm_channel_area_t *areas,
-                                       snd_pcm_uframes_t offset,
-                                       snd_pcm_uframes_t size,
-                                       snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
+                        const snd_pcm_channel_area_t *areas,
+                        snd_pcm_uframes_t offset,
+                        snd_pcm_uframes_t size,
+                        const snd_pcm_channel_area_t *slave_areas,
+                        snd_pcm_uframes_t slave_offset,
+                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_adpcm_t *adpcm = pcm->private_data;
-       snd_pcm_t *slave = adpcm->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
-               adpcm->func(areas, offset, 
-                           snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                           pcm->channels, frames,
-                           adpcm->getput_idx, adpcm->states);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       adpcm->func(areas, offset, 
+                   slave_areas, slave_offset,
+                   pcm->channels, size,
+                   adpcm->getput_idx, adpcm->states);
+       *slave_sizep = size;
+       return size;
 }
 
 static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out)
index 30ebf226cc6adf737c181c0fe483f74419ef6b41..98a57beaf2790d8bfc7eb6583ef799ff41588de6 100644 (file)
@@ -326,74 +326,44 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
-                                       const snd_pcm_channel_area_t *areas,
-                                       snd_pcm_uframes_t offset,
-                                       snd_pcm_uframes_t size,
-                                       snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
+                        const snd_pcm_channel_area_t *areas,
+                        snd_pcm_uframes_t offset,
+                        snd_pcm_uframes_t size,
+                        const snd_pcm_channel_area_t *slave_areas,
+                        snd_pcm_uframes_t slave_offset,
+                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_alaw_t *alaw = pcm->private_data;
-       snd_pcm_t *slave = alaw->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
-               alaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                          areas, offset, 
-                          pcm->channels, frames,
-                          alaw->getput_idx);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       alaw->func(slave_areas, slave_offset,
+                  areas, offset, 
+                  pcm->channels, size,
+                  alaw->getput_idx);
+       *slave_sizep = size;
+       return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
-                                      const snd_pcm_channel_area_t *areas,
-                                      snd_pcm_uframes_t offset,
-                                      snd_pcm_uframes_t size,
-                                      snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
+                       const snd_pcm_channel_area_t *areas,
+                       snd_pcm_uframes_t offset,
+                       snd_pcm_uframes_t size,
+                       const snd_pcm_channel_area_t *slave_areas,
+                       snd_pcm_uframes_t slave_offset,
+                       snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_alaw_t *alaw = pcm->private_data;
-       snd_pcm_t *slave = alaw->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
-               alaw->func(areas, offset, 
-                          snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                          pcm->channels, frames,
-                          alaw->getput_idx);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       alaw->func(areas, offset, 
+                  slave_areas, slave_offset,
+                  pcm->channels, size,
+                  alaw->getput_idx);
+       *slave_sizep = size;
+       return size;
 }
 
 static void snd_pcm_alaw_dump(snd_pcm_t *pcm, snd_output_t *out)
index cf06865a31cf5db8302695a3d2c4923eb331242f..510d0e1b1e4b043a4263a557902c910b30753a5c 100644 (file)
@@ -90,73 +90,40 @@ static int snd_pcm_copy_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_plugin_hw_params_slave);
 }
 
-static snd_pcm_sframes_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
-                                                 const snd_pcm_channel_area_t *areas,
-                                                 snd_pcm_uframes_t offset,
-                                                 snd_pcm_uframes_t size,
-                                                 snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_copy_write_areas(snd_pcm_t *pcm,
+                        const snd_pcm_channel_area_t *areas,
+                        snd_pcm_uframes_t offset,
+                        snd_pcm_uframes_t size,
+                        const snd_pcm_channel_area_t *slave_areas,
+                        snd_pcm_uframes_t slave_offset,
+                        snd_pcm_uframes_t *slave_sizep)
 {
-       snd_pcm_copy_t *copy = pcm->private_data;
-       snd_pcm_t *slave = copy->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
-               
-               snd_pcm_areas_copy(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                  areas, offset, 
-                                  pcm->channels, frames, pcm->format);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       snd_pcm_areas_copy(slave_areas, slave_offset,
+                          areas, offset,
+                          pcm->channels, size, pcm->format);
+       *slave_sizep = size;
+       return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_copy_read_areas(snd_pcm_t *pcm,
-                                                const snd_pcm_channel_area_t *areas,
-                                                snd_pcm_uframes_t offset,
-                                                snd_pcm_uframes_t size,
-                                                snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_copy_read_areas(snd_pcm_t *pcm,
+                       const snd_pcm_channel_area_t *areas,
+                       snd_pcm_uframes_t offset,
+                       snd_pcm_uframes_t size,
+                       const snd_pcm_channel_area_t *slave_areas,
+                       snd_pcm_uframes_t slave_offset,
+                       snd_pcm_uframes_t *slave_sizep)
 {
-       snd_pcm_copy_t *copy = pcm->private_data;
-       snd_pcm_t *slave = copy->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
-               snd_pcm_areas_copy(areas, offset, 
-                                  snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                  pcm->channels, frames, pcm->format);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       snd_pcm_areas_copy(areas, offset, 
+                          slave_areas, slave_offset,
+                          pcm->channels, size, pcm->format);
+       *slave_sizep = size;
+       return size;
 }
 
 static void snd_pcm_copy_dump(snd_pcm_t *pcm, snd_output_t *out)
index b3a2ca525705a1fb520a83c8207797087acd6fc6..8d7a61d0c7fec3c5dccf2d2289251ff4688d2fa9 100644 (file)
@@ -227,72 +227,42 @@ static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
-                                         const snd_pcm_channel_area_t *areas,
-                                         snd_pcm_uframes_t offset,
-                                         snd_pcm_uframes_t size,
-                                         snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_linear_write_areas(snd_pcm_t *pcm,
+                          const snd_pcm_channel_area_t *areas,
+                          snd_pcm_uframes_t offset,
+                          snd_pcm_uframes_t size,
+                          const snd_pcm_channel_area_t *slave_areas,
+                          snd_pcm_uframes_t slave_offset,
+                          snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_linear_t *linear = pcm->private_data;
-       snd_pcm_t *slave = linear->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
-               snd_pcm_linear_convert(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                      areas, offset, 
-                                      pcm->channels, frames, linear->conv_idx);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       snd_pcm_linear_convert(slave_areas, slave_offset,
+                              areas, offset, 
+                              pcm->channels, size, linear->conv_idx);
+       *slave_sizep = size;
+       return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_linear_read_areas(snd_pcm_t *pcm,
-                                        const snd_pcm_channel_area_t *areas,
-                                        snd_pcm_uframes_t offset,
-                                        snd_pcm_uframes_t size,
-                                        snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_linear_read_areas(snd_pcm_t *pcm,
+                         const snd_pcm_channel_area_t *areas,
+                         snd_pcm_uframes_t offset,
+                         snd_pcm_uframes_t size,
+                         const snd_pcm_channel_area_t *slave_areas,
+                         snd_pcm_uframes_t slave_offset,
+                         snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_linear_t *linear = pcm->private_data;
-       snd_pcm_t *slave = linear->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
-               snd_pcm_linear_convert(areas, offset, 
-                                      snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                      pcm->channels, frames, linear->conv_idx);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       snd_pcm_linear_convert(areas, offset, 
+                              slave_areas, slave_offset,
+                              pcm->channels, size, linear->conv_idx);
+       *slave_sizep = size;
+       return size;
 }
 
 static void snd_pcm_linear_dump(snd_pcm_t *pcm, snd_output_t *out)
index edeb5f70f1fe636340d51b1c1841d159f1924e28..13051555b5ada0576923e4e18c01e11830b9218f 100644 (file)
@@ -187,17 +187,17 @@ snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm);
 snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 
-typedef snd_pcm_sframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm, 
-                                            const snd_pcm_channel_area_t *areas,
-                                            snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
-                                            snd_pcm_uframes_t *slave_sizep);
+typedef snd_pcm_uframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm, 
+                                                      const snd_pcm_channel_area_t *areas,
+                                                      snd_pcm_uframes_t offset, 
+                                                      snd_pcm_uframes_t size);
 
 snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
-                          snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
-                          snd_pcm_xfer_areas_func_t func);
+                                    snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
+                                    snd_pcm_xfer_areas_func_t func);
 snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
-                           snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
-                           snd_pcm_xfer_areas_func_t func);
+                                     snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
+                                     snd_pcm_xfer_areas_func_t func);
 snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size);
 int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
index 1eee430bd67184047f90b72008e1c66fa9afbe55..54f9b2625cddbaa093ceb9a7f7b2be59cb58a29d 100644 (file)
@@ -143,57 +143,69 @@ void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
        *pcm->hw_ptr = hw_ptr;
 }
 
-snd_pcm_sframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
+snd_pcm_uframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
                                           const snd_pcm_channel_area_t *areas,
                                           snd_pcm_uframes_t offset,
-                                          snd_pcm_uframes_t size,
-                                          snd_pcm_uframes_t *slave_sizep)
+                                          snd_pcm_uframes_t size)
 {
-       snd_pcm_uframes_t xfer;
-       if (slave_sizep && *slave_sizep < size)
-               size = *slave_sizep;
-       xfer = 0;
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(pcm, size - xfer);
-               snd_pcm_sframes_t err;
-               snd_pcm_areas_copy(snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm),
+       const snd_pcm_channel_area_t *pcm_areas;
+       snd_pcm_uframes_t pcm_offset;
+       snd_pcm_uframes_t xfer = size;
+       assert(snd_pcm_mmap_playback_avail(pcm) >= size);
+       pcm_areas = snd_pcm_mmap_areas(pcm);
+       pcm_offset = snd_pcm_mmap_offset(pcm);
+       while (size > 0) {
+               snd_pcm_uframes_t frames = size;
+               snd_pcm_uframes_t cont = pcm->buffer_size - pcm_offset;
+               int err;
+               if (frames > cont)
+                       frames = cont;
+               snd_pcm_areas_copy(pcm_areas, pcm_offset,
                                   areas, offset, 
                                   pcm->channels, 
                                   frames, pcm->format);
                err = snd_pcm_mmap_forward(pcm, frames);
                assert(err == (snd_pcm_sframes_t)frames);
+               if (frames == cont)
+                       pcm_offset = 0;
+               else
+                       pcm_offset += frames;
                offset += frames;
-               xfer += frames;
+               size -= frames;
        }
-       if (slave_sizep)
-               *slave_sizep = xfer;
        return xfer;
 }
 
-snd_pcm_sframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
+snd_pcm_uframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
                                          const snd_pcm_channel_area_t *areas,
                                          snd_pcm_uframes_t offset,
-                                         snd_pcm_uframes_t size,
-                                         snd_pcm_uframes_t *slave_sizep)
+                                         snd_pcm_uframes_t size)
 {
-       snd_pcm_uframes_t xfer;
-       if (slave_sizep && *slave_sizep < size)
-               size = *slave_sizep;
-       xfer = 0;
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(pcm, size - xfer);
-               snd_pcm_sframes_t err;
+       const snd_pcm_channel_area_t *pcm_areas;
+       snd_pcm_uframes_t pcm_offset;
+       snd_pcm_uframes_t xfer = size;
+       assert(snd_pcm_mmap_capture_avail(pcm) >= size);
+       pcm_areas = snd_pcm_mmap_areas(pcm);
+       pcm_offset = snd_pcm_mmap_offset(pcm);
+       while (size > 0) {
+               snd_pcm_uframes_t frames = size;
+               snd_pcm_uframes_t cont = pcm->buffer_size - pcm_offset;
+               int err;
+               if (frames > cont)
+                       frames = cont;
                snd_pcm_areas_copy(areas, offset, 
-                                  snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm),
+                                  pcm_areas, pcm_offset,
                                   pcm->channels, 
                                   frames, pcm->format);
                err = snd_pcm_mmap_forward(pcm, frames);
                assert(err == (snd_pcm_sframes_t)frames);
+               if (frames == cont)
+                       pcm_offset = 0;
+               else
+                       pcm_offset += frames;
                offset += frames;
-               xfer += frames;
+               size -= frames;
        }
-       if (slave_sizep)
-               *slave_sizep = xfer;
        return xfer;
 }
 
index 3399a88232d084fc24be33ee9fed623b152cd548..8f7ff661a8f1346872a67f415d207a3606e674a6 100644 (file)
@@ -341,74 +341,44 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
-                                        const snd_pcm_channel_area_t *areas,
-                                        snd_pcm_uframes_t offset,
-                                        snd_pcm_uframes_t size,
-                                        snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
+                         const snd_pcm_channel_area_t *areas,
+                         snd_pcm_uframes_t offset,
+                         snd_pcm_uframes_t size,
+                         const snd_pcm_channel_area_t *slave_areas,
+                         snd_pcm_uframes_t slave_offset,
+                         snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_mulaw_t *mulaw = pcm->private_data;
-       snd_pcm_t *slave = mulaw->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
-               mulaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                           areas, offset, 
-                           pcm->channels, frames,
-                           mulaw->getput_idx);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       mulaw->func(slave_areas, slave_offset,
+                   areas, offset, 
+                   pcm->channels, size,
+                   mulaw->getput_idx);
+       *slave_sizep = size;
+       return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
-                                       const snd_pcm_channel_area_t *areas,
-                                       snd_pcm_uframes_t offset,
-                                       snd_pcm_uframes_t size,
-                                       snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
+                        const snd_pcm_channel_area_t *areas,
+                        snd_pcm_uframes_t offset,
+                        snd_pcm_uframes_t size,
+                        const snd_pcm_channel_area_t *slave_areas,
+                        snd_pcm_uframes_t slave_offset,
+                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_mulaw_t *mulaw = pcm->private_data;
-       snd_pcm_t *slave = mulaw->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
-               mulaw->func(areas, offset, 
-                           snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                           pcm->channels, frames,
-                           mulaw->getput_idx);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       mulaw->func(areas, offset, 
+                   slave_areas, slave_offset,
+                   pcm->channels, size,
+                   mulaw->getput_idx);
+       *slave_sizep = size;
+       return size;
 }
 
 static void snd_pcm_mulaw_dump(snd_pcm_t *pcm, snd_output_t *out)
index 0576aa7c82d2e7418646fd06530ca0951cf2bf61..2c9498a3235112ec212d30d89ab6d686c030524d 100644 (file)
@@ -408,7 +408,7 @@ static snd_pcm_sframes_t snd_pcm_multi_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
                snd_pcm_t *slave_i = multi->slaves[i].pcm;
                snd_pcm_uframes_t f = pos[i] - frames;
                if (f > 0)
-                       snd_pcm_mmap_appl_forward(slave_i, f);
+                       snd_pcm_mmap_forward(slave_i, f);
        }
        return frames;
 }
index cb7a7af7c72d55ce4b94f03d89d19854e9b51c06..a3a2d188024e24953283fbc9dd661a03cc74f8d6 100644 (file)
@@ -188,100 +188,159 @@ snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames
        return n;
 }
 
-snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
+snd_pcm_uframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
+                                            const snd_pcm_channel_area_t *areas,
+                                            snd_pcm_uframes_t offset,
+                                            snd_pcm_uframes_t size)
+{
+       snd_pcm_plugin_t *plugin = pcm->private_data;
+       snd_pcm_t *slave = plugin->slave;
+       const snd_pcm_channel_area_t *slave_areas;
+       snd_pcm_uframes_t slave_offset;
+       snd_pcm_uframes_t xfer = size;
+       slave_areas = snd_pcm_mmap_areas(slave);
+       slave_offset = snd_pcm_mmap_offset(slave);
+       while (size > 0) {
+               snd_pcm_uframes_t frames = size;
+               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
+               snd_pcm_uframes_t slave_frames = slave_cont;
+               frames = plugin->write(pcm, areas, offset, frames,
+                                      slave_areas, slave_offset, &slave_frames);
+               assert(slave_frames <= snd_pcm_mmap_playback_avail(slave));
+               snd_pcm_mmap_appl_forward(pcm, frames);
+               snd_pcm_mmap_hw_forward(pcm, frames);
+               snd_pcm_mmap_forward(slave, slave_frames);
+               offset += frames;
+               size -= frames;
+               if (slave_frames == slave_cont)
+                       slave_offset = 0;
+               else
+                       slave_offset += slave_frames;
+       }
+       return xfer;
+}
+
+snd_pcm_uframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
+                                           const snd_pcm_channel_area_t *areas,
+                                           snd_pcm_uframes_t offset,
+                                           snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
+       snd_pcm_t *slave = plugin->slave;
+       const snd_pcm_channel_area_t *slave_areas;
+       snd_pcm_uframes_t slave_offset;
+       snd_pcm_uframes_t xfer = size;
+       slave_areas = snd_pcm_mmap_areas(slave);
+       slave_offset = snd_pcm_mmap_offset(slave);
+       while (size > 0) {
+               snd_pcm_uframes_t frames = size;
+               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
+               snd_pcm_uframes_t slave_frames = slave_cont;
+               frames = plugin->write(pcm, areas, offset, frames,
+                                      slave_areas, slave_offset, &slave_frames);
+               assert(slave_frames <= snd_pcm_mmap_capture_avail(slave));
+               snd_pcm_mmap_appl_forward(pcm, frames);
+               snd_pcm_mmap_hw_forward(pcm, frames);
+               snd_pcm_mmap_forward(slave, slave_frames);
+               offset += frames;
+               size -= frames;
+               if (slave_frames == slave_cont)
+                       slave_offset = 0;
+               else
+                       slave_offset += slave_frames;
+       }
+       return xfer;
+}
+
+
+snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
+{
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_buf(pcm, areas, (void*)buffer);
-       frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write);
-       if (frames > 0)
-               snd_pcm_mmap_appl_forward(pcm, frames);
-       return frames;
+       return snd_pcm_write_areas(pcm, areas, 0, size, 
+                                  snd_pcm_plugin_write_areas);
 }
 
 snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
-       snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_bufs(pcm, areas, bufs);
-       frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write);
-       if (frames > 0)
-               snd_pcm_mmap_appl_forward(pcm, frames);
-       return frames;
+       return snd_pcm_write_areas(pcm, areas, 0, size,
+                                  snd_pcm_plugin_write_areas);
 }
 
 snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
-       snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_buf(pcm, areas, buffer);
-       frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read);
-       if (frames > 0)
-               snd_pcm_mmap_appl_forward(pcm, frames);
-       return frames;
+       return snd_pcm_read_areas(pcm, areas, 0, size,
+                                 snd_pcm_plugin_read_areas);
 }
 
 snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
-       snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_bufs(pcm, areas, bufs);
-       frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read);
-       if (frames > 0)
-               snd_pcm_mmap_appl_forward(pcm, frames);
-       return frames;
+       return snd_pcm_read_areas(pcm, areas, 0, size,
+                                 snd_pcm_plugin_read_areas);
 }
 
-snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t client_size)
+snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_t *slave = plugin->slave;
-       snd_pcm_uframes_t client_xfer = 0;
-       snd_pcm_uframes_t slave_xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       snd_pcm_sframes_t slave_size;
+       const snd_pcm_channel_area_t *areas, *slave_areas;
+       snd_pcm_uframes_t xfer, offset;
+       snd_pcm_uframes_t slave_offset, slave_size;
        if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
-               snd_pcm_mmap_appl_forward(pcm, client_size);
-               // snd_pcm_plugin_avail_update(pcm);
-               return client_size;
+               snd_pcm_mmap_appl_forward(pcm, size);
+               return size;
        }
        slave_size = snd_pcm_avail_update(slave);
        if (slave_size <= 0)
                return slave_size;
-       while (client_xfer < client_size &&
-              slave_xfer < (snd_pcm_uframes_t)slave_size) {
-               snd_pcm_uframes_t slave_frames = slave_size - slave_xfer;
-               snd_pcm_uframes_t client_frames = client_size - client_xfer;
-               snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+       areas = snd_pcm_mmap_areas(pcm);
+       offset = snd_pcm_mmap_hw_offset(pcm);
+       slave_areas = snd_pcm_mmap_areas(slave);
+       slave_offset = snd_pcm_mmap_offset(slave);
+       xfer = 0;
+       while (size && slave_size) {
+               snd_pcm_uframes_t frames = size;
                snd_pcm_uframes_t cont = pcm->buffer_size - offset;
-               if (cont < client_frames)
-                       client_frames = cont;
-               err = plugin->write(pcm, pcm->running_areas, offset,
-                                   client_frames, &slave_frames);
-               if (err < 0)
-                       break;
-               snd_pcm_mmap_appl_forward(pcm, err);
-               client_xfer += err;
-               slave_xfer += slave_frames;
+               snd_pcm_uframes_t slave_frames = slave_size;
+               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
+               if (frames > cont)
+                       frames = cont;
+               if (slave_frames > slave_cont)
+                       slave_frames = slave_cont;
+               frames = plugin->write(pcm, areas, offset, frames,
+                                      slave_areas, slave_offset, &slave_frames);
+               snd_pcm_mmap_appl_forward(pcm, frames);
+               snd_pcm_mmap_hw_forward(pcm, frames);
+               snd_pcm_mmap_forward(slave, slave_frames);
+               xfer += frames;
+               if (frames == cont)
+                       offset = 0;
+               else
+                       offset += frames;
+               size -= frames;
+               if (slave_frames == slave_cont)
+                       slave_offset = 0;
+               else
+                       slave_offset += slave_frames;
+               slave_size -= slave_frames;
        }
-       if (client_xfer > 0)
-               return client_xfer;
-       return err;
+       return xfer;
 }
 
 snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_t *slave = plugin->slave;
-       snd_pcm_uframes_t client_xfer;
-       snd_pcm_uframes_t slave_xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       snd_pcm_uframes_t client_size;
-       snd_pcm_sframes_t slave_size = snd_pcm_avail_update(slave);
+       const snd_pcm_channel_area_t *areas, *slave_areas;
+       snd_pcm_uframes_t xfer, offset, size;
+       snd_pcm_uframes_t slave_offset, slave_size;
+       slave_size = snd_pcm_avail_update(slave);
        if (slave_size <= 0)
                return slave_size;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK ||
@@ -289,26 +348,38 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
            pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED)
                return plugin->client_frames ?
                        plugin->client_frames(pcm, slave_size) : slave_size;
-       client_xfer = snd_pcm_mmap_capture_avail(pcm);
-       client_size = pcm->buffer_size;
-       while (slave_xfer < (snd_pcm_uframes_t)slave_size &&
-              client_xfer < client_size) {
-               snd_pcm_uframes_t slave_frames = slave_size - slave_xfer;
-               snd_pcm_uframes_t client_frames = client_size - client_xfer;
-               snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+       xfer = snd_pcm_mmap_capture_avail(pcm);
+       size = pcm->buffer_size - xfer;
+       areas = snd_pcm_mmap_areas(pcm);
+       offset = snd_pcm_mmap_hw_offset(pcm);
+       slave_areas = snd_pcm_mmap_areas(slave);
+       slave_offset = snd_pcm_mmap_offset(slave);
+       while (size && slave_size) {
+               snd_pcm_uframes_t frames = size;
                snd_pcm_uframes_t cont = pcm->buffer_size - offset;
-               if (cont < client_frames)
-                       client_frames = cont;
-               err = plugin->read(pcm, pcm->running_areas, offset,
-                                  client_frames, &slave_frames);
-               if (err < 0)
-                       break;
-               client_xfer += err;
-               slave_xfer += slave_frames;
+               snd_pcm_uframes_t slave_frames = slave_size;
+               snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
+               if (frames > cont)
+                       frames = cont;
+               if (slave_frames > slave_cont)
+                       slave_frames = slave_cont;
+               frames = plugin->read(pcm, areas, offset, frames,
+                                     slave_areas, slave_offset, &slave_frames);
+               snd_pcm_mmap_hw_forward(pcm, frames);
+               snd_pcm_mmap_forward(slave, slave_frames);
+               xfer += frames;
+               if (frames == cont)
+                       offset = 0;
+               else
+                       offset += frames;
+               size -= frames;
+               if (slave_frames == slave_cont)
+                       slave_offset = 0;
+               else
+                       slave_offset += slave_frames;
+               slave_size -= slave_frames;
        }
-       if (client_xfer > 0)
-               return client_xfer;
-       return err;
+       return xfer;
 }
 
 int snd_pcm_plugin_mmap(snd_pcm_t *pcm)
index 7d6a0375163e5a43f90e68bb87ce924384ac6d5f..760a8a8c77eba10e3cd0630efd0ddbcb8def2845 100644 (file)
  *
  */
   
+typedef snd_pcm_uframes_t (*snd_pcm_slave_xfer_areas_func_t)
+     (snd_pcm_t *pcm, 
+      const snd_pcm_channel_area_t *areas,
+      snd_pcm_uframes_t offset, 
+      snd_pcm_uframes_t size,
+      const snd_pcm_channel_area_t *slave_areas,
+      snd_pcm_uframes_t slave_offset, 
+      snd_pcm_uframes_t *slave_sizep);
+
 typedef struct {
        snd_pcm_t *slave;
        int close_slave;
-       snd_pcm_xfer_areas_func_t read;
-       snd_pcm_xfer_areas_func_t write;
+       snd_pcm_slave_xfer_areas_func_t read;
+       snd_pcm_slave_xfer_areas_func_t write;
        snd_pcm_sframes_t (*client_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
        snd_pcm_sframes_t (*slave_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
        int (*init)(snd_pcm_t *pcm);
index 1709f4adf476e99f2d2d4b70f8801b58a1a4981e..7d17a9eed3ad5352d98a4810cac8273b86bdef7f 100644 (file)
@@ -419,106 +419,39 @@ static int snd_pcm_rate_init(snd_pcm_t *pcm)
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
-                                       const snd_pcm_channel_area_t *areas,
-                                       snd_pcm_uframes_t client_offset,
-                                       snd_pcm_uframes_t client_size,
-                                       snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_rate_write_areas(snd_pcm_t *pcm,
+                        const snd_pcm_channel_area_t *areas,
+                        snd_pcm_uframes_t offset,
+                        snd_pcm_uframes_t size,
+                        const snd_pcm_channel_area_t *slave_areas,
+                        snd_pcm_uframes_t slave_offset,
+                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_t *slave = rate->plug.slave;
-       snd_pcm_uframes_t client_xfer = 0;
-       snd_pcm_uframes_t slave_xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       snd_pcm_uframes_t slave_size;
-       if (slave_sizep)
-               slave_size = *slave_sizep;
-       else
-               slave_size = INT_MAX;
-       assert(client_size > 0 && slave_size > 0);
-       while (client_xfer < client_size &&
-              slave_xfer < slave_size) {
-               snd_pcm_uframes_t src_frames, dst_frames;
-               src_frames = client_size - client_xfer;
-               dst_frames = snd_pcm_mmap_playback_xfer(slave, slave_size - slave_xfer);
-               src_frames = rate->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                       &dst_frames, 
-                                       areas, client_offset, src_frames,
-                                       pcm->channels,
-                                       rate->get_idx, rate->put_idx,
-                                       rate->pitch, rate->states);
-               assert(src_frames || dst_frames);
-               if (dst_frames > 0) {
-                       err = snd_pcm_mmap_forward(slave, dst_frames);
-                       if (err < 0)
-                               break;
-                       assert((snd_pcm_uframes_t)err == dst_frames);
-                       slave_xfer += dst_frames;
-               }
-
-               if (src_frames > 0) {
-                       client_offset += src_frames;
-                       client_xfer += src_frames;
-                       snd_pcm_mmap_hw_forward(pcm, src_frames);
-               }
-       }
-       if (client_xfer > 0 || slave_xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = slave_xfer;
-               return client_xfer;
-       }
-       return err;
+       return rate->func(slave_areas, slave_offset, slave_sizep, 
+                         areas, offset, size,
+                         pcm->channels,
+                         rate->get_idx, rate->put_idx,
+                         rate->pitch, rate->states);
 }
 
-static snd_pcm_sframes_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
-                                                const snd_pcm_channel_area_t *areas,
-                                                snd_pcm_uframes_t client_offset,
-                                                snd_pcm_uframes_t client_size,
-                                                snd_pcm_uframes_t *slave_sizep)
-
+static snd_pcm_uframes_t
+snd_pcm_rate_read_areas(snd_pcm_t *pcm,
+                        const snd_pcm_channel_area_t *areas,
+                        snd_pcm_uframes_t offset,
+                        snd_pcm_uframes_t size,
+                        const snd_pcm_channel_area_t *slave_areas,
+                        snd_pcm_uframes_t slave_offset,
+                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_t *slave = rate->plug.slave;
-       snd_pcm_uframes_t client_xfer = 0;
-       snd_pcm_uframes_t slave_xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       snd_pcm_uframes_t slave_size;
-       if (slave_sizep)
-               slave_size = *slave_sizep;
-       else
-               slave_size = INT_MAX;
-       assert(client_size > 0 && slave_size > 0);
-       while (client_xfer < client_size &&
-              slave_xfer < slave_size) {
-               snd_pcm_uframes_t src_frames, dst_frames;
-               dst_frames = client_size - client_xfer;
-               src_frames = snd_pcm_mmap_capture_xfer(slave, slave_size - slave_xfer);
-               src_frames = rate->func(areas, client_offset, &dst_frames,
-                                       snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                       src_frames,
-                                       pcm->channels,
-                                       rate->get_idx, rate->put_idx,
-                                       rate->pitch, rate->states);
-               assert(src_frames || dst_frames);
-               if (src_frames > 0) {
-                       err = snd_pcm_mmap_forward(slave, src_frames);
-                       if (err < 0)
-                               break;
-                       assert((snd_pcm_uframes_t)err == src_frames);
-                       slave_xfer += src_frames;
-               }
-               if (dst_frames > 0) {
-                       client_offset += dst_frames;
-                       client_xfer += dst_frames;
-                       snd_pcm_mmap_hw_forward(pcm, dst_frames);
-               }
-       }
-       if (client_xfer > 0 || slave_xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = slave_xfer;
-               return client_xfer;
-       }
-       return err;
+       *slave_sizep = rate->func(areas, offset, &size,
+                                 slave_areas, slave_offset, *slave_sizep,
+                                 pcm->channels,
+                                 rate->get_idx, rate->put_idx,
+                                 rate->pitch, rate->states);
+       return size;
 }
 
 snd_pcm_sframes_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
index 0145f49981753e954907c8c28a431eb53a9cccdb..db386c2135e9319d1591f39a7210f1e3b7f2c8a0 100644 (file)
@@ -571,72 +571,43 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
-                                                  const snd_pcm_channel_area_t *areas,
-                                                  snd_pcm_uframes_t offset,
-                                                  snd_pcm_uframes_t size,
-                                                  snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_route_write_areas(snd_pcm_t *pcm,
+                         const snd_pcm_channel_area_t *areas,
+                         snd_pcm_uframes_t offset,
+                         snd_pcm_uframes_t size,
+                         const snd_pcm_channel_area_t *slave_areas,
+                         snd_pcm_uframes_t slave_offset,
+                         snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_route_t *route = pcm->private_data;
        snd_pcm_t *slave = route->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
-               snd_pcm_route_convert(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                     areas, offset, 
-                                     slave->channels, frames, &route->params);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       snd_pcm_route_convert(slave_areas, slave_offset,
+                             areas, offset, 
+                             slave->channels, size, &route->params);
+       *slave_sizep = size;
+       return size;
 }
 
-static snd_pcm_sframes_t snd_pcm_route_read_areas(snd_pcm_t *pcm,
-                                                 const snd_pcm_channel_area_t *areas,
-                                                 snd_pcm_uframes_t offset,
-                                                 snd_pcm_uframes_t size,
-                                                 snd_pcm_uframes_t *slave_sizep)
+static snd_pcm_uframes_t
+snd_pcm_route_read_areas(snd_pcm_t *pcm,
+                        const snd_pcm_channel_area_t *areas,
+                        snd_pcm_uframes_t offset,
+                        snd_pcm_uframes_t size,
+                        const snd_pcm_channel_area_t *slave_areas,
+                        snd_pcm_uframes_t slave_offset,
+                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_route_t *route = pcm->private_data;
-       snd_pcm_t *slave = route->plug.slave;
-       snd_pcm_uframes_t xfer = 0;
-       snd_pcm_sframes_t err = 0;
-       if (slave_sizep && *slave_sizep < size)
+       if (size > *slave_sizep)
                size = *slave_sizep;
-       assert(size > 0);
-       while (xfer < size) {
-               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
-               snd_pcm_route_convert(areas, offset, 
-                                     snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
-                                     pcm->channels, frames, &route->params);
-               err = snd_pcm_mmap_forward(slave, frames);
-               if (err < 0)
-                       break;
-               assert((snd_pcm_uframes_t)err == frames);
-               offset += err;
-               xfer += err;
-               snd_pcm_mmap_hw_forward(pcm, err);
-       }
-       if (xfer > 0) {
-               if (slave_sizep)
-                       *slave_sizep = xfer;
-               return xfer;
-       }
-       return err;
+       snd_pcm_route_convert(areas, offset, 
+                             slave_areas, slave_offset,
+                             pcm->channels, size, &route->params);
+       *slave_sizep = size;
+       return size;
 }
 
 static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out)