@@ -543,11 +543,43 @@ static size_t audio_pcm_hw_conv_in(HWVoiceIn *hw, void *pcm_buf, size_t samples)
/*
* Soft voice (capture)
*/
+static void audio_pcm_sw_resample_in(SWVoiceIn *sw,
+ size_t frames_in_max, size_t frames_out_max,
+ size_t *total_in, size_t *total_out)
+{
+ HWVoiceIn *hw = sw->hw;
+ struct st_sample *src, *dst;
+ size_t live, rpos, frames_in, frames_out;
+
+ live = hw->total_samples_captured - sw->total_hw_samples_acquired;
+ rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size);
+
+ /* resample conv_buf from rpos to end of buffer */
+ src = hw->conv_buf.buffer + rpos;
+ frames_in = MIN(frames_in_max, hw->conv_buf.size - rpos);
+ dst = sw->resample_buf.buffer;
+ frames_out = frames_out_max;
+ st_rate_flow(sw->rate, src, dst, &frames_in, &frames_out);
+ rpos += frames_in;
+ *total_in = frames_in;
+ *total_out = frames_out;
+
+ /* resample conv_buf from start of buffer if there are input frames left */
+ if (frames_in_max - frames_in && rpos == hw->conv_buf.size) {
+ src = hw->conv_buf.buffer;
+ frames_in = frames_in_max - frames_in;
+ dst += frames_out;
+ frames_out = frames_out_max - frames_out;
+ st_rate_flow(sw->rate, src, dst, &frames_in, &frames_out);
+ *total_in += frames_in;
+ *total_out += frames_out;
+ }
+}
+
static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
{
HWVoiceIn *hw = sw->hw;
- size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
- struct st_sample *src, *dst = sw->resample_buf.buffer;
+ size_t samples, live, ret, swlim, total;
live = hw->total_samples_captured - sw->total_hw_samples_acquired;
if (!live) {
@@ -558,33 +590,12 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
return 0;
}
- rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size);
-
samples = size / sw->info.bytes_per_frame;
swlim = (live * sw->ratio) >> 32;
swlim = MIN (swlim, samples);
- while (swlim) {
- src = hw->conv_buf.buffer + rpos;
- if (hw->conv_buf.pos > rpos) {
- isamp = hw->conv_buf.pos - rpos;
- } else {
- isamp = hw->conv_buf.size - rpos;
- }
-
- if (!isamp) {
- break;
- }
- osamp = swlim;
-
- st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
- swlim -= osamp;
- rpos = (rpos + isamp) % hw->conv_buf.size;
- dst += osamp;
- ret += osamp;
- total += isamp;
- }
+ audio_pcm_sw_resample_in(sw, live, swlim, &total, &ret);
if (!hw->pcm_ops->volume_in) {
mixeng_volume(sw->resample_buf.buffer, ret, &sw->vol);