diff --git a/hal/audio_hw.c b/hal/audio_hw.c index cd72d514..3af4be12 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -3401,12 +3401,47 @@ static void register_sample_rate(uint32_t sample_rate, "%s: stream can not declare supporting its sample rate %x", __func__, sample_rate); } +static inline uint32_t lcm(uint32_t num1, uint32_t num2) +{ + uint32_t high = num1, low = num2, temp = 0; + + if (!num1 || !num2) + return 0; + + if (num1 < num2) { + high = num2; + low = num1; + } + + while (low != 0) { + temp = low; + low = high % low; + high = temp; + } + return (num1 * num2)/high; +} + +static inline uint32_t nearest_multiple(uint32_t num, uint32_t multiplier) +{ + uint32_t remainder = 0; + + if (!multiplier) + return num; + + remainder = num % multiplier; + if (remainder) + num += (multiplier - remainder); + + return num; +} + static size_t get_input_buffer_size(uint32_t sample_rate, audio_format_t format, int channel_count, bool is_low_latency) { size_t size = 0; + uint32_t bytes_per_period_sample = 0; if (check_input_parameters(sample_rate, format, channel_count) != 0) return 0; @@ -3415,15 +3450,16 @@ static size_t get_input_buffer_size(uint32_t sample_rate, if (is_low_latency) size = configured_low_latency_capture_period_size; - size *= audio_bytes_per_sample(format) * channel_count; + bytes_per_period_sample = audio_bytes_per_sample(format) * channel_count; + size *= bytes_per_period_sample; /* make sure the size is multiple of 32 bytes * At 48 kHz mono 16-bit PCM: * 5.000 ms = 240 frames = 15*16*1*2 = 480, a whole multiple of 32 (15) * 3.333 ms = 160 frames = 10*16*1*2 = 320, a whole multiple of 32 (10) + * Also, make sure the size is multiple of bytes per period sample */ - size += 0x1f; - size &= ~0x1f; + size = nearest_multiple(size, lcm(32, bytes_per_period_sample)); return size; }