1 /**
2 * Copyright (C) 2022 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 <IAudioSourceNode.h>
18 #include <ImsMediaAudioSource.h>
19 #include <ImsMediaTrace.h>
20 #include <ImsMediaAudioUtil.h>
21 #include <ImsMediaTimer.h>
22 #include <string.h>
23 #include <AudioConfig.h>
24 #include <RtpConfig.h>
25 #include <EvsParams.h>
26 #include <AnbrMode.h>
27
28 #define MAX_CODEC_EVS_AMR_IO_MODE 9
29
IAudioSourceNode(BaseSessionCallback * callback)30 IAudioSourceNode::IAudioSourceNode(BaseSessionCallback* callback) :
31 BaseNode(callback)
32 {
33 std::unique_ptr<ImsMediaAudioSource> recoder(new ImsMediaAudioSource());
34 mAudioSource = std::move(recoder);
35 mCodecType = 0;
36 mCodecMode = 0;
37 mRunningCodecMode = 0;
38 mFirstFrame = false;
39 mMediaDirection = 0;
40 mAnbrUplinkMode = 0;
41 mIsOctetAligned = false;
42 mIsDtxEnabled = false;
43 }
44
~IAudioSourceNode()45 IAudioSourceNode::~IAudioSourceNode() {}
46
GetNodeId()47 kBaseNodeId IAudioSourceNode::GetNodeId()
48 {
49 return kNodeIdAudioSource;
50 }
51
ProcessStart()52 ImsMediaResult IAudioSourceNode::ProcessStart()
53 {
54 IMLOGD2("[ProcessStart] codec[%d], mode[%d]", mCodecType, mCodecMode);
55
56 if (mAudioSource)
57 {
58 mAudioSource->SetUplinkCallback(this);
59 mAudioSource->SetCodec(mCodecType);
60 mRunningCodecMode = ImsMediaAudioUtil::GetMaximumAmrMode(mCodecType, mCodecMode);
61 mAudioSource->SetPtime(mPtime);
62 mAudioSource->SetSamplingRate(mSamplingRate * 1000);
63 mAudioSource->SetMediaDirection(mMediaDirection);
64 mAudioSource->SetDtxEnabled(mIsDtxEnabled);
65 mAudioSource->SetOctetAligned(mIsOctetAligned);
66
67 if (mCodecType == kAudioCodecEvs)
68 {
69 mAudioSource->SetEvsBandwidth((int32_t)mEvsBandwidth);
70 mAudioSource->SetEvsChAwOffset(mEvsChAwOffset);
71 mRunningCodecMode = ImsMediaAudioUtil::GetMaximumEvsMode(mCodecMode);
72 mAudioSource->SetEvsBitRate(
73 ImsMediaAudioUtil::ConvertEVSModeToBitRate(mRunningCodecMode));
74 }
75 mAudioSource->SetCodecMode(mRunningCodecMode);
76 IMLOGD1("[ProcessStart] running codec mode: %d", mRunningCodecMode);
77
78 if (mAudioSource->Start())
79 {
80 mNodeState = kNodeStateRunning;
81 mFirstFrame = false;
82 return RESULT_SUCCESS;
83 }
84 }
85 else
86 {
87 IMLOGE0("[IAudioSourceNode] Not able to start AudioSource");
88 }
89
90 return RESULT_NOT_READY;
91 }
92
Stop()93 void IAudioSourceNode::Stop()
94 {
95 IMLOGD0("[Stop]");
96
97 if (mAudioSource)
98 {
99 mAudioSource->Stop();
100 }
101
102 mNodeState = kNodeStateStopped;
103 }
104
IsRunTime()105 bool IAudioSourceNode::IsRunTime()
106 {
107 return true;
108 }
109
IsRunTimeStart()110 bool IAudioSourceNode::IsRunTimeStart()
111 {
112 return false;
113 }
114
IsSourceNode()115 bool IAudioSourceNode::IsSourceNode()
116 {
117 return true;
118 }
119
SetConfig(void * config)120 void IAudioSourceNode::SetConfig(void* config)
121 {
122 if (config == nullptr)
123 {
124 return;
125 }
126
127 AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
128 mCodecType = ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType());
129
130 if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
131 {
132 mCodecMode = pConfig->getAmrParams().getAmrMode();
133 mIsOctetAligned = pConfig->getAmrParams().getOctetAligned();
134 }
135 else if (mCodecType == kAudioCodecEvs)
136 {
137 mCodecMode = pConfig->getEvsParams().getEvsMode();
138 mEvsBandwidth = ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
139 pConfig->getEvsParams().getEvsBandwidth());
140 mEvsChAwOffset = pConfig->getEvsParams().getChannelAwareMode();
141
142 mAnbrUplinkMode = pConfig->getAnbrMode().getAnbrUplinkCodecMode();
143
144 if (mAnbrUplinkMode != 0 && mCodecMode != mAnbrUplinkMode)
145 {
146 mCodecMode = mAnbrUplinkMode;
147 IMLOGI2("[SetConfig] new codec mode: %d, uplink mode: %d", mCodecMode, mAnbrUplinkMode);
148 }
149 }
150
151 mMediaDirection = pConfig->getMediaDirection();
152 mSamplingRate = pConfig->getSamplingRateKHz();
153 mPtime = pConfig->getPtimeMillis();
154 mIsDtxEnabled = pConfig->getDtxEnabled();
155 }
156
IsSameConfig(void * config)157 bool IAudioSourceNode::IsSameConfig(void* config)
158 {
159 if (config == nullptr)
160 {
161 return true;
162 }
163
164 AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
165
166 if (mCodecType == ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType()))
167 {
168 if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
169 {
170 return (mCodecMode == pConfig->getAmrParams().getAmrMode() &&
171 mSamplingRate == pConfig->getSamplingRateKHz() &&
172 mMediaDirection == pConfig->getMediaDirection() &&
173 mIsDtxEnabled == pConfig->getDtxEnabled() &&
174 mIsOctetAligned == pConfig->getAmrParams().getOctetAligned());
175 }
176 else if (mCodecType == kAudioCodecEvs)
177 {
178 return (mCodecMode == pConfig->getEvsParams().getEvsMode() &&
179 mEvsBandwidth ==
180 ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
181 pConfig->getEvsParams().getEvsBandwidth()) &&
182 mEvsChAwOffset == pConfig->getEvsParams().getChannelAwareMode() &&
183 mSamplingRate == pConfig->getSamplingRateKHz() &&
184 mMediaDirection == pConfig->getMediaDirection() &&
185 mIsDtxEnabled == pConfig->getDtxEnabled());
186 }
187 }
188
189 return false;
190 }
191
onDataFrame(uint8_t * buffer,uint32_t size,int64_t timestamp,uint32_t flag)192 void IAudioSourceNode::onDataFrame(uint8_t* buffer, uint32_t size, int64_t timestamp, uint32_t flag)
193 {
194 IMLOGD_PACKET3(IM_PACKET_LOG_AUDIO, "[onDataFrame] size[%zu], TS[%ld], flag[%d]", size,
195 timestamp, flag);
196 SendDataToRearNode(MEDIASUBTYPE_UNDEFINED, buffer, size, ImsMediaTimer::GetTimeInMilliSeconds(),
197 !mFirstFrame, 0, MEDIASUBTYPE_UNDEFINED, ImsMediaTimer::GetTimeInMilliSeconds());
198
199 if (!mFirstFrame)
200 {
201 mFirstFrame = true;
202 }
203 }
204
ProcessCmr(const uint32_t cmrType,const uint32_t cmrDefine)205 void IAudioSourceNode::ProcessCmr(const uint32_t cmrType, const uint32_t cmrDefine)
206 {
207 IMLOGD2("[ProcessCmr] cmr type[%d], cmrDefine[%d]", cmrType, cmrDefine);
208
209 if (mAudioSource == nullptr)
210 {
211 return;
212 }
213
214 if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
215 {
216 if (cmrType == 15) // change mode to original one
217 {
218 int32_t mode = ImsMediaAudioUtil::GetMaximumAmrMode(mCodecType, mCodecMode);
219
220 if (mRunningCodecMode != mode)
221 {
222 mAudioSource->ProcessCmr(mode);
223 mRunningCodecMode = mode;
224 }
225 }
226 else
227 {
228 if (mRunningCodecMode != cmrType)
229 {
230 if (cmrType > mRunningCodecMode && mAnbrUplinkMode == 0)
231 {
232 triggerAnbrQuery(cmrType);
233 }
234 mAudioSource->ProcessCmr(cmrType);
235 mRunningCodecMode = cmrType;
236 }
237 }
238 }
239 else if (mCodecType == kAudioCodecEvs)
240 {
241 if (cmrType == kEvsCmrCodeTypeNoReq || cmrDefine == kEvsCmrCodeDefineNoReq)
242 {
243 int32_t mode = ImsMediaAudioUtil::GetMaximumEvsMode(mCodecMode);
244
245 if (mRunningCodecMode != mode)
246 {
247 mAudioSource->ProcessCmr(mode);
248 mRunningCodecMode = mode;
249 }
250 }
251 else
252 {
253 // triggering ANBR query- build triggerAnbrQuery (with mode: cmr)
254 int32_t mode = MAX_CODEC_EVS_AMR_IO_MODE;
255
256 if ((cmrDefine + mode) > mRunningCodecMode && mAnbrUplinkMode == 0)
257 {
258 triggerAnbrQuery(mode + cmrDefine);
259 }
260
261 switch (cmrType)
262 {
263 case kEvsCmrCodeTypeNb:
264 mEvsBandwidth = kEvsBandwidthNB;
265 mode += cmrDefine;
266 break;
267 case kEvsCmrCodeTypeWb:
268 mEvsBandwidth = kEvsBandwidthWB;
269 mode += cmrDefine;
270 break;
271 case kEvsCmrCodeTypeSwb:
272 mEvsBandwidth = kEvsBandwidthSWB;
273 mode += cmrDefine;
274 break;
275 case kEvsCmrCodeTypeFb:
276 mEvsBandwidth = kEvsBandwidthFB;
277 mode += cmrDefine;
278 break;
279 case kEvsCmrCodeTypeWbCha:
280 mEvsBandwidth = kEvsBandwidthWB;
281 mode = kImsAudioEvsPrimaryMode13200;
282 break;
283 case kEvsCmrCodeTypeSwbCha:
284 mEvsBandwidth = kEvsBandwidthSWB;
285 mode = kImsAudioEvsPrimaryMode13200;
286 break;
287 case kEvsCmrCodeTypeAmrIO:
288 mode = cmrDefine;
289 break;
290 default:
291 break;
292 }
293
294 if (cmrType == kEvsCmrCodeTypeWbCha || cmrType == kEvsCmrCodeTypeSwbCha)
295 {
296 switch (cmrDefine)
297 {
298 case kEvsCmrCodeDefineChaOffset2:
299 case kEvsCmrCodeDefineChaOffsetH2:
300 mEvsChAwOffset = 2;
301 break;
302 case kEvsCmrCodeDefineChaOffset3:
303 case kEvsCmrCodeDefineChaOffsetH3:
304 mEvsChAwOffset = 3;
305 break;
306 case kEvsCmrCodeDefineChaOffset5:
307 case kEvsCmrCodeDefineChaOffsetH5:
308 mEvsChAwOffset = 5;
309 break;
310 case kEvsCmrCodeDefineChaOffset7:
311 case kEvsCmrCodeDefineChaOffsetH7:
312 mEvsChAwOffset = 7;
313 break;
314 default:
315 mEvsChAwOffset = 3;
316 break;
317 }
318 }
319
320 mAudioSource->SetEvsBandwidth((int32_t)mEvsBandwidth);
321 mAudioSource->SetEvsChAwOffset(mEvsChAwOffset);
322
323 if (mode != mRunningCodecMode)
324 {
325 mRunningCodecMode = mode;
326 mAudioSource->SetEvsBitRate(
327 ImsMediaAudioUtil::ConvertEVSModeToBitRate(mRunningCodecMode));
328 mAudioSource->SetCodecMode(mRunningCodecMode);
329 }
330
331 mAudioSource->ProcessCmr(mRunningCodecMode);
332 }
333 }
334 }
335
triggerAnbrQuery(uint32_t cmr)336 void IAudioSourceNode::triggerAnbrQuery(uint32_t cmr)
337 {
338 AnbrMode param;
339
340 IMLOGD1("[triggerAnbrQuery] - mode : %d", cmr);
341
342 param.setAnbrUplinkCodecMode(cmr);
343 param.setAnbrDownlinkCodecMode(0);
344
345 AudioConfig* audioConfig = new AudioConfig();
346 audioConfig->setAnbrMode(param);
347
348 mCallback->SendEvent(kAudioTriggerAnbrQueryInd, reinterpret_cast<uint64_t>(audioConfig));
349 }
350