1 /*
2  * Copyright (C) 2020 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 #include <cmath>
18 #include <chrono>
19 #include <thread>
20 #include <unistd.h>
21 #include <audio_utils/channels.h>
22 #include <audio_utils/format.h>
23 #include <log/log.h>
24 #include <utils/ThreadDefs.h>
25 #include <utils/Timers.h>
26 #include "device_port_source.h"
27 #include "talsa.h"
28 #include "ring_buffer.h"
29 #include "audio_ops.h"
30 #include "util.h"
31 #include "debug.h"
32 
33 namespace android {
34 namespace hardware {
35 namespace audio {
36 namespace V6_0 {
37 namespace implementation {
38 
39 namespace {
40 
41 constexpr int kMaxJitterUs = 3000;  // Enforced by CTS, should be <= 6ms
42 
43 struct TinyalsaSource : public DevicePortSource {
TinyalsaSourceandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource44     TinyalsaSource(unsigned pcmCard, unsigned pcmDevice,
45                    const AudioConfig &cfg, uint64_t &frames)
46             : mStartNs(systemTime(SYSTEM_TIME_MONOTONIC))
47             , mSampleRateHz(cfg.sampleRateHz)
48             , mFrameSize(util::countChannels(cfg.channelMask) * sizeof(int16_t))
49             , mReadSizeFrames(cfg.frameCount)
50             , mFrames(frames)
51             , mRingBuffer(mFrameSize * cfg.frameCount * 3)
52             , mMixer(pcmCard)
53             , mPcm(talsa::pcmOpen(pcmCard, pcmDevice,
54                                   util::countChannels(cfg.channelMask),
55                                   cfg.sampleRateHz,
56                                   cfg.frameCount,
57                                   false /* isOut */)) {
58         mProduceThread = std::thread(&TinyalsaSource::producerThread, this);
59     }
60 
~TinyalsaSourceandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource61     ~TinyalsaSource() {
62         mProduceThreadRunning = false;
63         mProduceThread.join();
64     }
65 
getCapturePositionandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource66     Result getCapturePosition(uint64_t &frames, uint64_t &time) override {
67         const nsecs_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
68         const uint64_t nowFrames = getCaptureFrames(nowNs);
69         mFrames += (nowFrames - mPreviousFrames);
70         mPreviousFrames = nowFrames;
71 
72         frames = mFrames;
73         time = nowNs;
74         return Result::OK;
75     }
76 
getCaptureFramesandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource77     uint64_t getCaptureFrames(const nsecs_t nowNs) const {
78         return uint64_t(mSampleRateHz) * ns2us(nowNs - mStartNs) / 1000000;
79     }
80 
getAvailableFramesandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource81     uint64_t getAvailableFrames(const nsecs_t nowNs) const {
82         return getCaptureFrames(nowNs) - mSentFrames;
83     }
84 
getAvailableFramesNowandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource85     uint64_t getAvailableFramesNow() const {
86         return getAvailableFrames(systemTime(SYSTEM_TIME_MONOTONIC));
87     }
88 
getWaitFramesNowandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource89     size_t getWaitFramesNow(const size_t requestedFrames) const {
90         const size_t availableFrames = getAvailableFramesNow();
91         return (requestedFrames > availableFrames)
92             ? (requestedFrames - availableFrames) : 0;
93     }
94 
readandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource95     size_t read(float volume, size_t bytesToRead, IWriter &writer) override {
96         const size_t waitFrames = getWaitFramesNow(bytesToRead / mFrameSize);
97         const auto blockUntil =
98             std::chrono::high_resolution_clock::now() +
99                 + std::chrono::microseconds(waitFrames * 1000000 / mSampleRateHz);
100 
101         while (bytesToRead > 0) {
102             if (mRingBuffer.waitForConsumeAvailable(blockUntil
103                     + std::chrono::microseconds(kMaxJitterUs))) {
104                 if (mRingBuffer.availableToConsume() >= bytesToRead) {
105                     // Since the ring buffer has all bytes we need, make sure we
106                     // are not too early here: tinyalsa is jittery, we don't
107                     // want to go faster than SYSTEM_TIME_MONOTONIC
108                     std::this_thread::sleep_until(blockUntil);
109                 }
110 
111                 auto chunk = mRingBuffer.getConsumeChunk();
112                 const size_t writeBufSzBytes = std::min(chunk.size, bytesToRead);
113 
114                 aops::multiplyByVolume(volume,
115                                        static_cast<int16_t *>(chunk.data),
116                                        writeBufSzBytes / sizeof(int16_t));
117 
118                 writer(chunk.data, writeBufSzBytes);
119                 LOG_ALWAYS_FATAL_IF(mRingBuffer.consume(chunk, writeBufSzBytes) < writeBufSzBytes);
120 
121                 bytesToRead -= writeBufSzBytes;
122                 mSentFrames += writeBufSzBytes / mFrameSize;
123             } else {
124                 ALOGW("TinyalsaSource::%s:%d pcm_read was late delivering "
125                       "frames, inserting %zu us of silence",
126                       __func__, __LINE__,
127                       size_t(1000000 * bytesToRead / mFrameSize / mSampleRateHz));
128 
129                 static const uint8_t zeroes[256] = {0};
130 
131                 while (bytesToRead > 0) {
132                     const size_t nZeroFrames =
133                         std::min(bytesToRead, sizeof(zeroes)) / mFrameSize;
134                     const size_t nZeroBytes = nZeroFrames * mFrameSize;
135 
136                     writer(zeroes, nZeroBytes);
137                     mSentFrames += nZeroFrames;
138                     bytesToRead -= nZeroBytes;
139                 }
140                 break;
141             }
142         }
143 
144         return mFramesLost.exchange(0);
145     }
146 
producerThreadandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource147     void producerThread() {
148         util::setThreadPriority(PRIORITY_URGENT_AUDIO);
149         std::vector<uint8_t> readBuf(mReadSizeFrames * mFrameSize);
150 
151         while (mProduceThreadRunning) {
152             const size_t bytesLost = mRingBuffer.makeRoomForProduce(readBuf.size());
153             mFramesLost += bytesLost / mFrameSize;
154 
155             auto produceChunk = mRingBuffer.getProduceChunk();
156             if (produceChunk.size < readBuf.size()) {
157                 const size_t sz = doRead(readBuf.data(), readBuf.size());
158                 if (sz > 0) {
159                     LOG_ALWAYS_FATAL_IF(mRingBuffer.produce(readBuf.data(), sz) < sz);
160                 }
161             } else {
162                 const size_t sz = doRead(produceChunk.data, readBuf.size());
163                 if (sz > 0) {
164                     LOG_ALWAYS_FATAL_IF(mRingBuffer.produce(readBuf.size()) < sz);
165                 }
166             }
167         }
168     }
169 
doReadandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource170     size_t doRead(void *dst, size_t sz) {
171         const int res = ::pcm_read(mPcm.get(), dst, sz);
172         if (res < 0) {
173             ALOGW("TinyalsaSource::%s:%d pcm_read failed with res=%d",
174                   __func__, __LINE__, res);
175             return 0;
176         }
177 
178         return sz;
179     }
180 
createandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::TinyalsaSource181     static std::unique_ptr<TinyalsaSource> create(unsigned pcmCard,
182                                                   unsigned pcmDevice,
183                                                   const AudioConfig &cfg,
184                                                   size_t writerBufferSizeHint,
185                                                   uint64_t &frames) {
186         (void)writerBufferSizeHint;
187 
188         auto src = std::make_unique<TinyalsaSource>(pcmCard, pcmDevice,
189                                                     cfg, frames);
190         if (src->mMixer && src->mPcm) {
191             return src;
192         } else {
193             return FAILURE(nullptr);
194         }
195     }
196 
197 private:
198     const nsecs_t mStartNs;
199     const unsigned mSampleRateHz;
200     const unsigned mFrameSize;
201     const unsigned mReadSizeFrames;
202     uint64_t &mFrames;
203     uint64_t mPreviousFrames = 0;
204     uint64_t mSentFrames = 0;
205     std::atomic<uint32_t> mFramesLost = 0;
206     RingBuffer mRingBuffer;
207     talsa::Mixer mMixer;
208     talsa::PcmPtr mPcm;
209     std::thread mProduceThread;
210     std::atomic<bool> mProduceThreadRunning = true;
211 };
212 
213 template <class G> struct GeneratedSource : public DevicePortSource {
GeneratedSourceandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::GeneratedSource214     GeneratedSource(const AudioConfig &cfg,
215                     size_t writerBufferSizeHint,
216                     uint64_t &frames,
217                     G generator)
218             : mWriteBuffer(writerBufferSizeHint / sizeof(int16_t))
219             , mFrames(frames)
220             , mStartNs(systemTime(SYSTEM_TIME_MONOTONIC))
221             , mSampleRateHz(cfg.sampleRateHz)
222             , mNChannels(util::countChannels(cfg.channelMask))
223             , mGenerator(std::move(generator)) {}
224 
getCapturePositionandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::GeneratedSource225     Result getCapturePosition(uint64_t &frames, uint64_t &time) override {
226         const nsecs_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
227         const uint64_t nowFrames = getCaptureFrames(nowNs);
228         mFrames += (nowFrames - mPreviousFrames);
229         mPreviousFrames = nowFrames;
230         frames = mFrames;
231         time = nowNs;
232         return Result::OK;
233     }
234 
getCaptureFramesandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::GeneratedSource235     uint64_t getCaptureFrames(const nsecs_t nowNs) const {
236         return uint64_t(mSampleRateHz) * ns2us(nowNs - mStartNs) / 1000000;
237     }
238 
getAvailableFramesandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::GeneratedSource239     uint64_t getAvailableFrames(const nsecs_t nowNs) const {
240         return getCaptureFrames(nowNs) - mSentFrames;
241     }
242 
readandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::GeneratedSource243     size_t read(float volume, size_t bytesToRead, IWriter &writer) override {
244         mWriteBuffer.resize(bytesToRead / sizeof(int16_t));
245 
246         int16_t *samples = mWriteBuffer.data();
247         const unsigned nChannels = mNChannels;
248         const unsigned requestedFrames = bytesToRead / nChannels / sizeof(*samples);
249 
250         unsigned availableFrames;
251         while (true) {
252             const nsecs_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
253             availableFrames = getAvailableFrames(nowNs);
254             if (availableFrames < requestedFrames / 2) {
255                 const unsigned neededMoreFrames = requestedFrames / 2 - availableFrames;
256 
257                 using namespace std::chrono_literals;
258                 std::this_thread::sleep_for(1s * neededMoreFrames / mSampleRateHz);
259             } else {
260                 break;
261             }
262         }
263 
264         const unsigned nFrames = std::min(requestedFrames, availableFrames);
265         mGenerator(samples, nFrames);
266         const size_t sizeBytes = nFrames * nChannels * sizeof(*samples);
267         if (nChannels > 1) {
268             adjust_channels(samples, 1, samples, nChannels,
269                             sizeof(*samples), sizeBytes);
270         }
271         mSentFrames += nFrames;
272 
273         aops::multiplyByVolume(volume,
274                                mWriteBuffer.data(),
275                                sizeBytes / sizeof(int16_t));
276 
277         writer(mWriteBuffer.data(), sizeBytes);
278         return 0;
279     }
280 
281 private:
282     std::vector<int16_t> mWriteBuffer;
283     uint64_t &mFrames;
284     const nsecs_t mStartNs;
285     const unsigned mSampleRateHz;
286     const unsigned mNChannels;
287     uint64_t mPreviousFrames = 0;
288     uint64_t mSentFrames = 0;
289     G mGenerator;
290 };
291 
convertFloatsToInt16(const std::vector<float> & pcmFloat)292 std::vector<int16_t> convertFloatsToInt16(const std::vector<float> &pcmFloat) {
293     std::vector<int16_t> pcmI16(pcmFloat.size());
294 
295     memcpy_by_audio_format(pcmI16.data(),   AUDIO_FORMAT_PCM_16_BIT,
296                            pcmFloat.data(), AUDIO_FORMAT_PCM_FLOAT,
297                            pcmFloat.size());
298 
299     return pcmI16;
300 }
301 
302 // https://en.wikipedia.org/wiki/Busy_signal
303 struct BusySignalGenerator {
BusySignalGeneratorandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::BusySignalGenerator304     explicit BusySignalGenerator(const uint32_t sampleRateHz) : mSampleRateHz(sampleRateHz) {
305         // 24/480 = 31/620, mValues must contain 50ms of audio samples
306         const size_t sz = sampleRateHz / 20;
307         std::vector<float> pcm(sz);
308         for (unsigned i = 0; i < sz; ++i) {
309             const double a = double(i) * M_PI * 2 / sampleRateHz;
310             pcm[i] = .5 * (sin(480 * a) + sin(620 * a));
311         }
312         mValues = convertFloatsToInt16(pcm);
313     }
314 
operator ()android::hardware::audio::V6_0::implementation::__anond1989e5f0111::BusySignalGenerator315     void operator()(int16_t* s, size_t n) {
316         const unsigned rate = mSampleRateHz;
317         const unsigned rateHalf = rate / 2;
318         const int16_t *const vals = mValues.data();
319         const size_t valsSz = mValues.size();
320         size_t i = mI;
321 
322         while (n > 0) {
323             size_t len;
324             if (i < rateHalf) {
325                 const size_t valsOff = i % valsSz;
326                 len = std::min(n, std::min(rateHalf - i, valsSz - valsOff));
327                 memcpy(s, vals + valsOff, len * sizeof(*s));
328             } else {
329                 len = std::min(n, rate - i);
330                 memset(s, 0, len * sizeof(*s));
331             }
332             s += len;
333             i = (i + len) % rate;
334             n -= len;
335         }
336 
337         mI = i;
338     }
339 
340 private:
341     const unsigned mSampleRateHz;
342     std::vector<int16_t> mValues;
343     size_t mI = 0;
344 };
345 
346 struct RepeatGenerator {
RepeatGeneratorandroid::hardware::audio::V6_0::implementation::__anond1989e5f0111::RepeatGenerator347     explicit RepeatGenerator(const std::vector<float> &pcm)
348             : mValues(convertFloatsToInt16(pcm)) {}
349 
operator ()android::hardware::audio::V6_0::implementation::__anond1989e5f0111::RepeatGenerator350     void operator()(int16_t* s, size_t n) {
351         const int16_t *const vals = mValues.data();
352         const size_t valsSz = mValues.size();
353         size_t i = mI;
354 
355         while (n > 0) {
356             const size_t len = std::min(n, valsSz - i);
357             memcpy(s, vals + i, len * sizeof(*s));
358             s += len;
359             i = (i + len) % valsSz;
360             n -= len;
361         }
362 
363         mI = i;
364     }
365 
366 private:
367     const std::vector<int16_t> mValues;
368     size_t mI = 0;
369 };
370 
generateSinePattern(uint32_t sampleRateHz,double freq,double amp)371 std::vector<float> generateSinePattern(uint32_t sampleRateHz,
372                                        double freq,
373                                        double amp) {
374     std::vector<float> result(3 * sampleRateHz / freq + .5);
375 
376     for (size_t i = 0; i < result.size(); ++i) {
377         const double a = double(i) * M_PI * 2 / sampleRateHz;
378         result[i] = amp * sin(a * freq);
379     }
380 
381     return result;
382 }
383 
384 template <class G> std::unique_ptr<GeneratedSource<G>>
createGeneratedSource(const AudioConfig & cfg,size_t writerBufferSizeHint,uint64_t & frames,G generator)385 createGeneratedSource(const AudioConfig &cfg,
386                       size_t writerBufferSizeHint,
387                       uint64_t &frames,
388                       G generator) {
389     return std::make_unique<GeneratedSource<G>>(cfg,
390                                                 writerBufferSizeHint,
391                                                 frames,
392                                                 std::move(generator));
393 }
394 
395 }  // namespace
396 
397 std::unique_ptr<DevicePortSource>
create(size_t writerBufferSizeHint,const DeviceAddress & address,const AudioConfig & cfg,const hidl_bitfield<AudioOutputFlag> & flags,uint64_t & frames)398 DevicePortSource::create(size_t writerBufferSizeHint,
399                          const DeviceAddress &address,
400                          const AudioConfig &cfg,
401                          const hidl_bitfield<AudioOutputFlag> &flags,
402                          uint64_t &frames) {
403     (void)flags;
404 
405     if (cfg.format != AudioFormat::PCM_16_BIT) {
406         ALOGE("%s:%d Only PCM_16_BIT is supported", __func__, __LINE__);
407         return FAILURE(nullptr);
408     }
409 
410     switch (address.device) {
411     case AudioDevice::IN_BUILTIN_MIC:
412         return TinyalsaSource::create(talsa::kPcmCard, talsa::kPcmDevice,
413                                       cfg, writerBufferSizeHint, frames);
414 
415     case AudioDevice::IN_TELEPHONY_RX:
416         return createGeneratedSource(cfg, writerBufferSizeHint, frames,
417                                      BusySignalGenerator(cfg.sampleRateHz));
418 
419     case AudioDevice::IN_FM_TUNER:
420         return createGeneratedSource(
421             cfg, writerBufferSizeHint, frames,
422             RepeatGenerator(generateSinePattern(cfg.sampleRateHz, 440.0, 1.0)));
423 
424     default:
425         ALOGE("%s:%d unsupported device: %x", __func__, __LINE__, address.device);
426         return FAILURE(nullptr);
427     }
428 }
429 
430 }  // namespace implementation
431 }  // namespace V6_0
432 }  // namespace audio
433 }  // namespace hardware
434 }  // namespace android
435