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