Improved plugin code (simpler, faster and multithread ready)

This commit is contained in:
Abramo Bagnara 2001-02-27 13:42:12 +00:00
parent afde2cfab2
commit 3830b168ef
13 changed files with 407 additions and 564 deletions

View 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) if (frames > (snd_pcm_uframes_t) avail)
frames = avail; frames = avail;
assert(frames != 0); assert(frames != 0);
err = func(pcm, areas, offset, frames, 0); err = func(pcm, areas, offset, frames);
if (err < 0) if (err < 0)
break; break;
assert((snd_pcm_uframes_t)err == frames); 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) if (frames > (snd_pcm_uframes_t) avail)
frames = avail; frames = avail;
assert(frames != 0); assert(frames != 0);
err = func(pcm, areas, offset, frames, 0); err = func(pcm, areas, offset, frames);
if (err < 0) if (err < 0)
break; break;
assert((snd_pcm_uframes_t)err == frames); assert((snd_pcm_uframes_t)err == frames);

View file

@ -452,74 +452,44 @@ static int snd_pcm_adpcm_init(snd_pcm_t *pcm)
return 0; return 0;
} }
static snd_pcm_sframes_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_adpcm_t *adpcm = pcm->private_data;
snd_pcm_t *slave = adpcm->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); adpcm->func(slave_areas, slave_offset,
while (xfer < size) { areas, offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer); pcm->channels, size,
adpcm->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), adpcm->getput_idx, adpcm->states);
areas, offset, *slave_sizep = size;
pcm->channels, frames, return size;
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;
} }
static snd_pcm_sframes_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_adpcm_t *adpcm = pcm->private_data;
snd_pcm_t *slave = adpcm->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); adpcm->func(areas, offset,
while (xfer < size) { slave_areas, slave_offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer); pcm->channels, size,
adpcm->func(areas, offset, adpcm->getput_idx, adpcm->states);
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), *slave_sizep = size;
pcm->channels, frames, return size;
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;
} }
static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out) static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out)

View file

@ -326,74 +326,44 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
return 0; return 0;
} }
static snd_pcm_sframes_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_alaw_t *alaw = pcm->private_data;
snd_pcm_t *slave = alaw->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); alaw->func(slave_areas, slave_offset,
while (xfer < size) { areas, offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer); pcm->channels, size,
alaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), alaw->getput_idx);
areas, offset, *slave_sizep = size;
pcm->channels, frames, return size;
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;
} }
static snd_pcm_sframes_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_alaw_t *alaw = pcm->private_data;
snd_pcm_t *slave = alaw->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); alaw->func(areas, offset,
while (xfer < size) { slave_areas, slave_offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer); pcm->channels, size,
alaw->func(areas, offset, alaw->getput_idx);
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), *slave_sizep = size;
pcm->channels, frames, return size;
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;
} }
static void snd_pcm_alaw_dump(snd_pcm_t *pcm, snd_output_t *out) static void snd_pcm_alaw_dump(snd_pcm_t *pcm, snd_output_t *out)

View 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); snd_pcm_plugin_hw_params_slave);
} }
static snd_pcm_sframes_t snd_pcm_copy_write_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_copy_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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; if (size > *slave_sizep)
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)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); snd_pcm_areas_copy(slave_areas, slave_offset,
while (xfer < size) { areas, offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer); pcm->channels, size, pcm->format);
*slave_sizep = size;
snd_pcm_areas_copy(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), return size;
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;
} }
static snd_pcm_sframes_t snd_pcm_copy_read_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_copy_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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; if (size > *slave_sizep)
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)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); snd_pcm_areas_copy(areas, offset,
while (xfer < size) { slave_areas, slave_offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer); pcm->channels, size, pcm->format);
snd_pcm_areas_copy(areas, offset, *slave_sizep = size;
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), return size;
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;
} }
static void snd_pcm_copy_dump(snd_pcm_t *pcm, snd_output_t *out) static void snd_pcm_copy_dump(snd_pcm_t *pcm, snd_output_t *out)

View file

@ -227,72 +227,42 @@ static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
return 0; return 0;
} }
static snd_pcm_sframes_t snd_pcm_linear_write_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_linear_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_linear_t *linear = pcm->private_data;
snd_pcm_t *slave = linear->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); snd_pcm_linear_convert(slave_areas, slave_offset,
while (xfer < size) { areas, offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer); pcm->channels, size, linear->conv_idx);
snd_pcm_linear_convert(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), *slave_sizep = size;
areas, offset, return size;
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;
} }
static snd_pcm_sframes_t snd_pcm_linear_read_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_linear_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_linear_t *linear = pcm->private_data;
snd_pcm_t *slave = linear->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); snd_pcm_linear_convert(areas, offset,
while (xfer < size) { slave_areas, slave_offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer); pcm->channels, size, linear->conv_idx);
snd_pcm_linear_convert(areas, offset, *slave_sizep = size;
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), return size;
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;
} }
static void snd_pcm_linear_dump(snd_pcm_t *pcm, snd_output_t *out) static void snd_pcm_linear_dump(snd_pcm_t *pcm, snd_output_t *out)

View 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_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); 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, typedef snd_pcm_uframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset, snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep); 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_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_uframes_t offset, snd_pcm_uframes_t size,
snd_pcm_xfer_areas_func_t func); 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_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_uframes_t offset, snd_pcm_uframes_t size,
snd_pcm_xfer_areas_func_t func); 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_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); 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); int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);

View 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; *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, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset, snd_pcm_uframes_t offset,
snd_pcm_uframes_t size, snd_pcm_uframes_t size)
snd_pcm_uframes_t *slave_sizep)
{ {
snd_pcm_uframes_t xfer; const snd_pcm_channel_area_t *pcm_areas;
if (slave_sizep && *slave_sizep < size) snd_pcm_uframes_t pcm_offset;
size = *slave_sizep; snd_pcm_uframes_t xfer = size;
xfer = 0; assert(snd_pcm_mmap_playback_avail(pcm) >= size);
while (xfer < size) { pcm_areas = snd_pcm_mmap_areas(pcm);
snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(pcm, size - xfer); pcm_offset = snd_pcm_mmap_offset(pcm);
snd_pcm_sframes_t err; while (size > 0) {
snd_pcm_areas_copy(snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm), 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, areas, offset,
pcm->channels, pcm->channels,
frames, pcm->format); frames, pcm->format);
err = snd_pcm_mmap_forward(pcm, frames); err = snd_pcm_mmap_forward(pcm, frames);
assert(err == (snd_pcm_sframes_t)frames); assert(err == (snd_pcm_sframes_t)frames);
if (frames == cont)
pcm_offset = 0;
else
pcm_offset += frames;
offset += frames; offset += frames;
xfer += frames; size -= frames;
} }
if (slave_sizep)
*slave_sizep = xfer;
return 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, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset, snd_pcm_uframes_t offset,
snd_pcm_uframes_t size, snd_pcm_uframes_t size)
snd_pcm_uframes_t *slave_sizep)
{ {
snd_pcm_uframes_t xfer; const snd_pcm_channel_area_t *pcm_areas;
if (slave_sizep && *slave_sizep < size) snd_pcm_uframes_t pcm_offset;
size = *slave_sizep; snd_pcm_uframes_t xfer = size;
xfer = 0; assert(snd_pcm_mmap_capture_avail(pcm) >= size);
while (xfer < size) { pcm_areas = snd_pcm_mmap_areas(pcm);
snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(pcm, size - xfer); pcm_offset = snd_pcm_mmap_offset(pcm);
snd_pcm_sframes_t err; 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_areas_copy(areas, offset,
snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm), pcm_areas, pcm_offset,
pcm->channels, pcm->channels,
frames, pcm->format); frames, pcm->format);
err = snd_pcm_mmap_forward(pcm, frames); err = snd_pcm_mmap_forward(pcm, frames);
assert(err == (snd_pcm_sframes_t)frames); assert(err == (snd_pcm_sframes_t)frames);
if (frames == cont)
pcm_offset = 0;
else
pcm_offset += frames;
offset += frames; offset += frames;
xfer += frames; size -= frames;
} }
if (slave_sizep)
*slave_sizep = xfer;
return xfer; return xfer;
} }

View file

@ -341,74 +341,44 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
return 0; return 0;
} }
static snd_pcm_sframes_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_mulaw_t *mulaw = pcm->private_data;
snd_pcm_t *slave = mulaw->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); mulaw->func(slave_areas, slave_offset,
while (xfer < size) { areas, offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer); pcm->channels, size,
mulaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), mulaw->getput_idx);
areas, offset, *slave_sizep = size;
pcm->channels, frames, return size;
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;
} }
static snd_pcm_sframes_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_mulaw_t *mulaw = pcm->private_data;
snd_pcm_t *slave = mulaw->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); mulaw->func(areas, offset,
while (xfer < size) { slave_areas, slave_offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer); pcm->channels, size,
mulaw->func(areas, offset, mulaw->getput_idx);
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), *slave_sizep = size;
pcm->channels, frames, return size;
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;
} }
static void snd_pcm_mulaw_dump(snd_pcm_t *pcm, snd_output_t *out) static void snd_pcm_mulaw_dump(snd_pcm_t *pcm, snd_output_t *out)

View 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_t *slave_i = multi->slaves[i].pcm;
snd_pcm_uframes_t f = pos[i] - frames; snd_pcm_uframes_t f = pos[i] - frames;
if (f > 0) if (f > 0)
snd_pcm_mmap_appl_forward(slave_i, f); snd_pcm_mmap_forward(slave_i, f);
} }
return frames; return frames;
} }

View file

@ -188,100 +188,159 @@ snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames
return n; 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_plugin_t *plugin = pcm->private_data;
snd_pcm_channel_area_t areas[pcm->channels]; snd_pcm_t *slave = plugin->slave;
snd_pcm_sframes_t frames; const snd_pcm_channel_area_t *slave_areas;
snd_pcm_areas_from_buf(pcm, areas, (void*)buffer); snd_pcm_uframes_t slave_offset;
frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write); snd_pcm_uframes_t xfer = size;
if (frames > 0) 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_appl_forward(pcm, frames);
return 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_areas_from_buf(pcm, areas, (void*)buffer);
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_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_channel_area_t areas[pcm->channels];
snd_pcm_sframes_t frames;
snd_pcm_areas_from_bufs(pcm, areas, bufs); snd_pcm_areas_from_bufs(pcm, areas, bufs);
frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write); return snd_pcm_write_areas(pcm, areas, 0, size,
if (frames > 0) snd_pcm_plugin_write_areas);
snd_pcm_mmap_appl_forward(pcm, frames);
return frames;
} }
snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size) 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_channel_area_t areas[pcm->channels];
snd_pcm_sframes_t frames;
snd_pcm_areas_from_buf(pcm, areas, buffer); snd_pcm_areas_from_buf(pcm, areas, buffer);
frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read); return snd_pcm_read_areas(pcm, areas, 0, size,
if (frames > 0) snd_pcm_plugin_read_areas);
snd_pcm_mmap_appl_forward(pcm, frames);
return frames;
} }
snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size) 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_channel_area_t areas[pcm->channels];
snd_pcm_sframes_t frames;
snd_pcm_areas_from_bufs(pcm, areas, bufs); snd_pcm_areas_from_bufs(pcm, areas, bufs);
frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read); return snd_pcm_read_areas(pcm, areas, 0, size,
if (frames > 0) snd_pcm_plugin_read_areas);
snd_pcm_mmap_appl_forward(pcm, frames);
return frames;
} }
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_plugin_t *plugin = pcm->private_data;
snd_pcm_t *slave = plugin->slave; snd_pcm_t *slave = plugin->slave;
snd_pcm_uframes_t client_xfer = 0; const snd_pcm_channel_area_t *areas, *slave_areas;
snd_pcm_uframes_t slave_xfer = 0; snd_pcm_uframes_t xfer, offset;
snd_pcm_sframes_t err = 0; snd_pcm_uframes_t slave_offset, slave_size;
snd_pcm_sframes_t slave_size;
if (pcm->stream == SND_PCM_STREAM_CAPTURE) { if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
snd_pcm_mmap_appl_forward(pcm, client_size); snd_pcm_mmap_appl_forward(pcm, size);
// snd_pcm_plugin_avail_update(pcm); return size;
return client_size;
} }
slave_size = snd_pcm_avail_update(slave); slave_size = snd_pcm_avail_update(slave);
if (slave_size <= 0) if (slave_size <= 0)
return slave_size; return slave_size;
while (client_xfer < client_size && areas = snd_pcm_mmap_areas(pcm);
slave_xfer < (snd_pcm_uframes_t)slave_size) { offset = snd_pcm_mmap_hw_offset(pcm);
snd_pcm_uframes_t slave_frames = slave_size - slave_xfer; slave_areas = snd_pcm_mmap_areas(slave);
snd_pcm_uframes_t client_frames = client_size - client_xfer; slave_offset = snd_pcm_mmap_offset(slave);
snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); xfer = 0;
while (size && slave_size) {
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t cont = pcm->buffer_size - offset; snd_pcm_uframes_t cont = pcm->buffer_size - offset;
if (cont < client_frames) snd_pcm_uframes_t slave_frames = slave_size;
client_frames = cont; snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
err = plugin->write(pcm, pcm->running_areas, offset, if (frames > cont)
client_frames, &slave_frames); frames = cont;
if (err < 0) if (slave_frames > slave_cont)
break; slave_frames = slave_cont;
snd_pcm_mmap_appl_forward(pcm, err); frames = plugin->write(pcm, areas, offset, frames,
client_xfer += err; slave_areas, slave_offset, &slave_frames);
slave_xfer += 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 xfer;
return client_xfer;
return err;
} }
snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm) snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
{ {
snd_pcm_plugin_t *plugin = pcm->private_data; snd_pcm_plugin_t *plugin = pcm->private_data;
snd_pcm_t *slave = plugin->slave; snd_pcm_t *slave = plugin->slave;
snd_pcm_uframes_t client_xfer; const snd_pcm_channel_area_t *areas, *slave_areas;
snd_pcm_uframes_t slave_xfer = 0; snd_pcm_uframes_t xfer, offset, size;
snd_pcm_sframes_t err = 0; snd_pcm_uframes_t slave_offset, slave_size;
snd_pcm_uframes_t client_size; slave_size = snd_pcm_avail_update(slave);
snd_pcm_sframes_t slave_size = snd_pcm_avail_update(slave);
if (slave_size <= 0) if (slave_size <= 0)
return slave_size; return slave_size;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK || 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) pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED)
return plugin->client_frames ? return plugin->client_frames ?
plugin->client_frames(pcm, slave_size) : slave_size; plugin->client_frames(pcm, slave_size) : slave_size;
client_xfer = snd_pcm_mmap_capture_avail(pcm); xfer = snd_pcm_mmap_capture_avail(pcm);
client_size = pcm->buffer_size; size = pcm->buffer_size - xfer;
while (slave_xfer < (snd_pcm_uframes_t)slave_size && areas = snd_pcm_mmap_areas(pcm);
client_xfer < client_size) { offset = snd_pcm_mmap_hw_offset(pcm);
snd_pcm_uframes_t slave_frames = slave_size - slave_xfer; slave_areas = snd_pcm_mmap_areas(slave);
snd_pcm_uframes_t client_frames = client_size - client_xfer; slave_offset = snd_pcm_mmap_offset(slave);
snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); while (size && slave_size) {
snd_pcm_uframes_t frames = size;
snd_pcm_uframes_t cont = pcm->buffer_size - offset; snd_pcm_uframes_t cont = pcm->buffer_size - offset;
if (cont < client_frames) snd_pcm_uframes_t slave_frames = slave_size;
client_frames = cont; snd_pcm_uframes_t slave_cont = slave->buffer_size - slave_offset;
err = plugin->read(pcm, pcm->running_areas, offset, if (frames > cont)
client_frames, &slave_frames); frames = cont;
if (err < 0) if (slave_frames > slave_cont)
break; slave_frames = slave_cont;
client_xfer += err; frames = plugin->read(pcm, areas, offset, frames,
slave_xfer += slave_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 xfer;
return client_xfer;
return err;
} }
int snd_pcm_plugin_mmap(snd_pcm_t *pcm) int snd_pcm_plugin_mmap(snd_pcm_t *pcm)

View file

@ -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 { typedef struct {
snd_pcm_t *slave; snd_pcm_t *slave;
int close_slave; int close_slave;
snd_pcm_xfer_areas_func_t read; snd_pcm_slave_xfer_areas_func_t read;
snd_pcm_xfer_areas_func_t write; 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 (*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); snd_pcm_sframes_t (*slave_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
int (*init)(snd_pcm_t *pcm); int (*init)(snd_pcm_t *pcm);

View file

@ -419,106 +419,39 @@ static int snd_pcm_rate_init(snd_pcm_t *pcm)
return 0; return 0;
} }
static snd_pcm_sframes_t snd_pcm_rate_write_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_rate_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t client_offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t client_size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_rate_t *rate = pcm->private_data;
snd_pcm_t *slave = rate->plug.slave; return rate->func(slave_areas, slave_offset, slave_sizep,
snd_pcm_uframes_t client_xfer = 0; areas, offset, size,
snd_pcm_uframes_t slave_xfer = 0; pcm->channels,
snd_pcm_sframes_t err = 0; rate->get_idx, rate->put_idx,
snd_pcm_uframes_t slave_size; rate->pitch, rate->states);
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;
} }
static snd_pcm_sframes_t snd_pcm_rate_read_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_rate_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t client_offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t client_size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_rate_t *rate = pcm->private_data;
snd_pcm_t *slave = rate->plug.slave; *slave_sizep = rate->func(areas, offset, &size,
snd_pcm_uframes_t client_xfer = 0; slave_areas, slave_offset, *slave_sizep,
snd_pcm_uframes_t slave_xfer = 0; pcm->channels,
snd_pcm_sframes_t err = 0; rate->get_idx, rate->put_idx,
snd_pcm_uframes_t slave_size; rate->pitch, rate->states);
if (slave_sizep) return size;
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;
} }
snd_pcm_sframes_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, snd_pcm_sframes_t frames) snd_pcm_sframes_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, snd_pcm_sframes_t frames)

View file

@ -571,72 +571,43 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
return 0; return 0;
} }
static snd_pcm_sframes_t snd_pcm_route_write_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_route_write_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_route_t *route = pcm->private_data;
snd_pcm_t *slave = route->plug.slave; snd_pcm_t *slave = route->plug.slave;
snd_pcm_uframes_t xfer = 0; if (size > *slave_sizep)
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); snd_pcm_route_convert(slave_areas, slave_offset,
while (xfer < size) { areas, offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer); slave->channels, size, &route->params);
snd_pcm_route_convert(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), *slave_sizep = size;
areas, offset, return size;
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;
} }
static snd_pcm_sframes_t snd_pcm_route_read_areas(snd_pcm_t *pcm, static snd_pcm_uframes_t
const snd_pcm_channel_area_t *areas, snd_pcm_route_read_areas(snd_pcm_t *pcm,
snd_pcm_uframes_t offset, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t size, snd_pcm_uframes_t offset,
snd_pcm_uframes_t *slave_sizep) 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_route_t *route = pcm->private_data;
snd_pcm_t *slave = route->plug.slave; if (size > *slave_sizep)
snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep; size = *slave_sizep;
assert(size > 0); snd_pcm_route_convert(areas, offset,
while (xfer < size) { slave_areas, slave_offset,
snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer); pcm->channels, size, &route->params);
snd_pcm_route_convert(areas, offset, *slave_sizep = size;
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), return size;
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;
} }
static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out) static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out)