From: Abramo Bagnara Date: Tue, 27 Feb 2001 13:42:12 +0000 (+0000) Subject: Improved plugin code (simpler, faster and multithread ready) X-Git-Tag: v1.0.3~940 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=3830b168ef1f5a130c62b70debf00f0160e6b863;p=alsa-lib.git Improved plugin code (simpler, faster and multithread ready) --- diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index d868eef2..8a37d433 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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); diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c index cdd61a84..6d033ccf 100644 --- a/src/pcm/pcm_adpcm.c +++ b/src/pcm/pcm_adpcm.c @@ -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) diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c index 30ebf226..98a57bea 100644 --- a/src/pcm/pcm_alaw.c +++ b/src/pcm/pcm_alaw.c @@ -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) diff --git a/src/pcm/pcm_copy.c b/src/pcm/pcm_copy.c index cf06865a..510d0e1b 100644 --- a/src/pcm/pcm_copy.c +++ b/src/pcm/pcm_copy.c @@ -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) diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c index b3a2ca52..8d7a61d0 100644 --- a/src/pcm/pcm_linear.c +++ b/src/pcm/pcm_linear.c @@ -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) diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index edeb5f70..13051555 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -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); diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c index 1eee430b..54f9b262 100644 --- a/src/pcm/pcm_mmap.c +++ b/src/pcm/pcm_mmap.c @@ -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; } diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c index 3399a882..8f7ff661 100644 --- a/src/pcm/pcm_mulaw.c +++ b/src/pcm/pcm_mulaw.c @@ -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) diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index 0576aa7c..2c9498a3 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -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; } diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index cb7a7af7..a3a2d188 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -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) diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h index 7d6a0375..760a8a8c 100644 --- a/src/pcm/pcm_plugin.h +++ b/src/pcm/pcm_plugin.h @@ -19,11 +19,20 @@ * */ +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); diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index 1709f4ad..7d17a9ee 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -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) diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c index 0145f499..db386c21 100644 --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -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)