|
@@ -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);
|