1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <array> 20 #include <cstdint> 21 #include <memory> 22 #include <vector> 23 24 #include "common/message_loop_thread.h" 25 26 namespace bluetooth::audio::asrc { 27 28 class SourceAudioHalAsrc { 29 public: 30 // The Asynchronous Sample Rate Conversion (ASRC) is set up from the PCM 31 // stream characteristics and the length, expressed in us, of the buffers. 32 // 33 // A transmission `burst` is proposed, to fulfill the audio pipeline 34 // buffering. After an initial delay of `burst_delay_ms`, a burst of 35 // `num_burst_buffers` is generated. By experience, it looks like some 36 // controllers discard and acknowledge the first packets without following 37 // transmission intervals. This behavior leads to dumping initial buffers. The 38 // `burst_delay_ms` helps to ensure that the synchronization with the 39 // transmission intervals is done. 40 41 SourceAudioHalAsrc(bluetooth::common::MessageLoopThread* thread, int channels, 42 int sample_rate, int bit_depth, int interval_us, 43 int num_burst_buffers = 2, int burst_delay_ms = 500); 44 45 ~SourceAudioHalAsrc(); 46 47 // Takes an input buffer, and returns a list of resamples buffers locked to 48 // the cadence of the transmission. The input and output buffers have a fixed 49 // size, deducted from the PCM characteristics, given to the constructor. 50 // 51 // The data of `in` mest be aligned to `int16_t` or `int32_t` for respectively 52 // bit depth less or equal to 16, or greater. 53 // 54 55 std::vector<const std::vector<uint8_t>*> Run(const std::vector<uint8_t>& in); 56 57 private: 58 const int sample_rate_; 59 const int bit_depth_; 60 const int interval_us_; 61 62 unsigned burst_delay_us_; 63 std::vector<const std::vector<uint8_t>*> burst_buffers_; 64 65 unsigned stream_us_; 66 double drift_z0_, drift_us_; 67 unsigned out_counter_; 68 69 size_t buffers_size_; 70 71 struct { 72 std::array<std::vector<uint8_t>, 3> pool; 73 int initial_buffering; 74 int index, offset; 75 } buffers_; 76 77 class ClockRecovery; 78 std::unique_ptr<ClockRecovery> clock_recovery_; 79 80 class Resampler; 81 std::unique_ptr<std::vector<Resampler>> resamplers_; 82 struct { 83 unsigned seconds; 84 int samples; 85 } resampler_pos_; 86 87 template <typename T> 88 void Resample(double, const std::vector<uint8_t>&, 89 std::vector<const std::vector<uint8_t>*>*, uint32_t*); 90 91 friend class SourceAudioHalAsrcTest; 92 }; 93 94 } // namespace bluetooth::audio::asrc 95