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 <log/log.h>
18 #include <cutils/bitops.h>
19 #include <system/audio.h>
20 #include "util.h"
21 
22 namespace android {
23 namespace hardware {
24 namespace audio {
25 namespace V6_0 {
26 namespace implementation {
27 namespace util {
28 
29 namespace {
30 
31 const std::array<uint32_t, 8> kSupportedRatesHz = {
32     8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000
33 };
34 
35 const std::array<hidl_bitfield<AudioChannelMask>, 4> kSupportedInChannelMask = {
36     AudioChannelMask::IN_LEFT | 0,
37     AudioChannelMask::IN_RIGHT | 0,
38     AudioChannelMask::IN_FRONT | 0,
39     AudioChannelMask::IN_STEREO | 0,
40 };
41 
42 const std::array<hidl_bitfield<AudioChannelMask>, 4> kSupportedOutChannelMask = {
43     AudioChannelMask::OUT_FRONT_LEFT | 0,
44     AudioChannelMask::OUT_FRONT_RIGHT | 0,
45     AudioChannelMask::OUT_FRONT_CENTER | 0,
46     AudioChannelMask::OUT_STEREO | 0,
47 };
48 
49 const std::array<AudioFormat, 1> kSupportedAudioFormats = {
50     AudioFormat::PCM_16_BIT,
51 };
52 
checkSampleRateHz(uint32_t value,uint32_t & suggest)53 bool checkSampleRateHz(uint32_t value, uint32_t &suggest) {
54     for (const uint32_t supported : kSupportedRatesHz) {
55         if (value <= supported) {
56             suggest = supported;
57             return (value == supported);
58         }
59     }
60 
61     suggest = kSupportedRatesHz.back();
62     return false;
63 }
64 
getBufferSizeFrames(size_t duration_ms,uint32_t sample_rate)65 size_t getBufferSizeFrames(size_t duration_ms, uint32_t sample_rate) {
66     return sample_rate * duration_ms / 1000;
67 }
68 
69 }  // namespace
70 
getMicrophoneInfo()71 MicrophoneInfo getMicrophoneInfo() {
72     MicrophoneInfo mic;
73 
74     mic.deviceId = "mic_goldfish";
75     mic.group = 0;
76     mic.indexInTheGroup = 0;
77     mic.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
78     mic.maxSpl = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
79     mic.minSpl = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
80     mic.directionality = AudioMicrophoneDirectionality::UNKNOWN;
81     mic.position.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
82     mic.position.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
83     mic.position.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
84     mic.orientation.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
85     mic.orientation.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
86     mic.orientation.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
87 
88     return mic;
89 }
90 
countChannels(hidl_bitfield<AudioChannelMask> mask)91 size_t countChannels(hidl_bitfield<AudioChannelMask> mask) {
92     return popcount(mask);
93 }
94 
getBytesPerSample(AudioFormat format)95 size_t getBytesPerSample(AudioFormat format) {
96     return audio_bytes_per_sample(static_cast<audio_format_t>(format));
97 }
98 
checkAudioConfig(bool isOut,size_t duration_ms,const AudioConfig & cfg,AudioConfig & suggested)99 bool checkAudioConfig(bool isOut,
100                       size_t duration_ms,
101                       const AudioConfig &cfg,
102                       AudioConfig &suggested) {
103     bool valid = checkSampleRateHz(cfg.sampleRateHz, suggested.sampleRateHz);
104 
105     if (isOut) {
106         if (std::find(kSupportedOutChannelMask.begin(),
107                       kSupportedOutChannelMask.end(),
108                       cfg.channelMask) == kSupportedOutChannelMask.end()) {
109             suggested.channelMask = AudioChannelMask::OUT_STEREO | 0;
110             valid = false;
111         } else {
112             suggested.channelMask = cfg.channelMask;
113         }
114     } else {
115         if (std::find(kSupportedInChannelMask.begin(),
116                       kSupportedInChannelMask.end(),
117                       cfg.channelMask) == kSupportedInChannelMask.end()) {
118             suggested.channelMask = AudioChannelMask::IN_STEREO | 0;
119             valid = false;
120         } else {
121             suggested.channelMask = cfg.channelMask;
122         }
123     }
124 
125     if (std::find(kSupportedAudioFormats.begin(),
126                   kSupportedAudioFormats.end(),
127                   cfg.format) == kSupportedAudioFormats.end()) {
128         suggested.format = AudioFormat::PCM_16_BIT;
129         valid = false;
130     } else {
131         suggested.format = cfg.format;
132     }
133 
134     suggested.offloadInfo = cfg.offloadInfo;    // don't care
135 
136     suggested.frameCount = (cfg.frameCount == 0)
137         ? getBufferSizeFrames(duration_ms, suggested.sampleRateHz)
138         : cfg.frameCount;
139 
140     return valid;
141 }
142 
StreamPosition()143 StreamPosition::StreamPosition() : mTimestamp(systemTime(SYSTEM_TIME_MONOTONIC)) {}
144 
addFrames(uint64_t n)145 void StreamPosition::addFrames(uint64_t n) {
146     mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
147     mFrames += n;
148 }
149 
now(const size_t sampleRateHz,uint64_t & frames,nsecs_t & timestamp) const150 void StreamPosition::now(const size_t sampleRateHz,
151                          uint64_t &frames,
152                          nsecs_t &timestamp) const {
153     const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
154     const uint64_t deltaUs = ns2us(now - mTimestamp);
155 
156     frames = mFrames + sampleRateHz * deltaUs / 1000000;
157     timestamp = now;
158 }
159 
reset()160 void StreamPosition::reset() {
161     *this = StreamPosition();
162 }
163 
164 }  // namespace util
165 }  // namespace implementation
166 }  // namespace V6_0
167 }  // namespace audio
168 }  // namespace hardware
169 }  // namespace android
170