Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: webrtc/voice_engine/voe_volume_control_impl.cc

Issue 1347353004: Reduce LS_INFO spam from voice_engine/. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/voice_engine/voe_video_sync_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 // set the actual volume using the audio mixer 76 // set the actual volume using the audio mixer
77 if (_shared->audio_device()->SetSpeakerVolume(spkrVol) != 0) { 77 if (_shared->audio_device()->SetSpeakerVolume(spkrVol) != 0) {
78 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError, 78 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
79 "SetSpeakerVolume() failed to set speaker volume"); 79 "SetSpeakerVolume() failed to set speaker volume");
80 return -1; 80 return -1;
81 } 81 }
82 return 0; 82 return 0;
83 } 83 }
84 84
85 int VoEVolumeControlImpl::GetSpeakerVolume(unsigned int& volume) { 85 int VoEVolumeControlImpl::GetSpeakerVolume(unsigned int& volume) {
86 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
87 "GetSpeakerVolume()");
88 86
89 if (!_shared->statistics().Initialized()) { 87 if (!_shared->statistics().Initialized()) {
90 _shared->SetLastError(VE_NOT_INITED, kTraceError); 88 _shared->SetLastError(VE_NOT_INITED, kTraceError);
91 return -1; 89 return -1;
92 } 90 }
93 91
94 uint32_t spkrVol(0); 92 uint32_t spkrVol(0);
95 uint32_t maxVol(0); 93 uint32_t maxVol(0);
96 94
97 if (_shared->audio_device()->SpeakerVolume(&spkrVol) != 0) { 95 if (_shared->audio_device()->SpeakerVolume(&spkrVol) != 0) {
98 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError, 96 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
99 "GetSpeakerVolume() unable to get speaker volume"); 97 "GetSpeakerVolume() unable to get speaker volume");
100 return -1; 98 return -1;
101 } 99 }
102 100
103 // scale: [0, MaxSpeakerVolume] -> [0, kMaxVolumeLevel] 101 // scale: [0, MaxSpeakerVolume] -> [0, kMaxVolumeLevel]
104 if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0) { 102 if (_shared->audio_device()->MaxSpeakerVolume(&maxVol) != 0) {
105 _shared->SetLastError( 103 _shared->SetLastError(
106 VE_GET_MIC_VOL_ERROR, kTraceError, 104 VE_GET_MIC_VOL_ERROR, kTraceError,
107 "GetSpeakerVolume() unable to get max speaker volume"); 105 "GetSpeakerVolume() unable to get max speaker volume");
108 return -1; 106 return -1;
109 } 107 }
110 // Round the value and avoid floating computation. 108 // Round the value and avoid floating computation.
111 volume = 109 volume =
112 (uint32_t)((spkrVol * kMaxVolumeLevel + (int)(maxVol / 2)) / (maxVol)); 110 (uint32_t)((spkrVol * kMaxVolumeLevel + (int)(maxVol / 2)) / (maxVol));
113 111
114 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
115 "GetSpeakerVolume() => volume=%d", volume);
116 return 0; 112 return 0;
117 } 113 }
118 114
119 int VoEVolumeControlImpl::SetMicVolume(unsigned int volume) { 115 int VoEVolumeControlImpl::SetMicVolume(unsigned int volume) {
120 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 116 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
121 "SetMicVolume(volume=%u)", volume); 117 "SetMicVolume(volume=%u)", volume);
122 118
123 if (!_shared->statistics().Initialized()) { 119 if (!_shared->statistics().Initialized()) {
124 _shared->SetLastError(VE_NOT_INITED, kTraceError); 120 _shared->SetLastError(VE_NOT_INITED, kTraceError);
125 return -1; 121 return -1;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 // set the actual volume using the audio mixer 158 // set the actual volume using the audio mixer
163 if (_shared->audio_device()->SetMicrophoneVolume(micVol) != 0) { 159 if (_shared->audio_device()->SetMicrophoneVolume(micVol) != 0) {
164 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError, 160 _shared->SetLastError(VE_MIC_VOL_ERROR, kTraceError,
165 "SetMicVolume() failed to set mic volume"); 161 "SetMicVolume() failed to set mic volume");
166 return -1; 162 return -1;
167 } 163 }
168 return 0; 164 return 0;
169 } 165 }
170 166
171 int VoEVolumeControlImpl::GetMicVolume(unsigned int& volume) { 167 int VoEVolumeControlImpl::GetMicVolume(unsigned int& volume) {
172 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
173 "GetMicVolume()");
174
175 if (!_shared->statistics().Initialized()) { 168 if (!_shared->statistics().Initialized()) {
176 _shared->SetLastError(VE_NOT_INITED, kTraceError); 169 _shared->SetLastError(VE_NOT_INITED, kTraceError);
177 return -1; 170 return -1;
178 } 171 }
179 172
180 uint32_t micVol(0); 173 uint32_t micVol(0);
181 uint32_t maxVol(0); 174 uint32_t maxVol(0);
182 175
183 if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0) { 176 if (_shared->audio_device()->MicrophoneVolume(&micVol) != 0) {
184 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError, 177 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
185 "GetMicVolume() unable to get microphone volume"); 178 "GetMicVolume() unable to get microphone volume");
186 return -1; 179 return -1;
187 } 180 }
188 181
189 // scale: [0, MaxMicrophoneVolume] -> [0, kMaxVolumeLevel] 182 // scale: [0, MaxMicrophoneVolume] -> [0, kMaxVolumeLevel]
190 if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0) { 183 if (_shared->audio_device()->MaxMicrophoneVolume(&maxVol) != 0) {
191 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError, 184 _shared->SetLastError(VE_GET_MIC_VOL_ERROR, kTraceError,
192 "GetMicVolume() unable to get max microphone volume"); 185 "GetMicVolume() unable to get max microphone volume");
193 return -1; 186 return -1;
194 } 187 }
195 if (micVol < maxVol) { 188 if (micVol < maxVol) {
196 // Round the value and avoid floating point calculation. 189 // Round the value and avoid floating point calculation.
197 volume = 190 volume =
198 (uint32_t)((micVol * kMaxVolumeLevel + (int)(maxVol / 2)) / (maxVol)); 191 (uint32_t)((micVol * kMaxVolumeLevel + (int)(maxVol / 2)) / (maxVol));
199 } else { 192 } else {
200 // Truncate the value to the kMaxVolumeLevel. 193 // Truncate the value to the kMaxVolumeLevel.
201 volume = kMaxVolumeLevel; 194 volume = kMaxVolumeLevel;
202 } 195 }
203
204 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
205 "GetMicVolume() => volume=%d", volume);
206 return 0; 196 return 0;
207 } 197 }
208 198
209 int VoEVolumeControlImpl::SetInputMute(int channel, bool enable) { 199 int VoEVolumeControlImpl::SetInputMute(int channel, bool enable) {
210 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 200 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
211 "SetInputMute(channel=%d, enable=%d)", channel, enable); 201 "SetInputMute(channel=%d, enable=%d)", channel, enable);
212 202
213 if (!_shared->statistics().Initialized()) { 203 if (!_shared->statistics().Initialized()) {
214 _shared->SetLastError(VE_NOT_INITED, kTraceError); 204 _shared->SetLastError(VE_NOT_INITED, kTraceError);
215 return -1; 205 return -1;
216 } 206 }
217 if (channel == -1) { 207 if (channel == -1) {
218 // Mute before demultiplexing <=> affects all channels 208 // Mute before demultiplexing <=> affects all channels
219 return _shared->transmit_mixer()->SetMute(enable); 209 return _shared->transmit_mixer()->SetMute(enable);
220 } 210 }
221 // Mute after demultiplexing <=> affects one channel only 211 // Mute after demultiplexing <=> affects one channel only
222 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 212 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
223 voe::Channel* channelPtr = ch.channel(); 213 voe::Channel* channelPtr = ch.channel();
224 if (channelPtr == NULL) { 214 if (channelPtr == NULL) {
225 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 215 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
226 "SetInputMute() failed to locate channel"); 216 "SetInputMute() failed to locate channel");
227 return -1; 217 return -1;
228 } 218 }
229 return channelPtr->SetMute(enable); 219 return channelPtr->SetMute(enable);
230 } 220 }
231 221
232 int VoEVolumeControlImpl::GetInputMute(int channel, bool& enabled) { 222 int VoEVolumeControlImpl::GetInputMute(int channel, bool& enabled) {
233 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
234 "GetInputMute(channel=%d)", channel);
235
236 if (!_shared->statistics().Initialized()) { 223 if (!_shared->statistics().Initialized()) {
237 _shared->SetLastError(VE_NOT_INITED, kTraceError); 224 _shared->SetLastError(VE_NOT_INITED, kTraceError);
238 return -1; 225 return -1;
239 } 226 }
240 if (channel == -1) { 227 if (channel == -1) {
241 enabled = _shared->transmit_mixer()->Mute(); 228 enabled = _shared->transmit_mixer()->Mute();
242 } else { 229 } else {
243 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 230 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
244 voe::Channel* channelPtr = ch.channel(); 231 voe::Channel* channelPtr = ch.channel();
245 if (channelPtr == NULL) { 232 if (channelPtr == NULL) {
246 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 233 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
247 "SetInputMute() failed to locate channel"); 234 "SetInputMute() failed to locate channel");
248 return -1; 235 return -1;
249 } 236 }
250 enabled = channelPtr->Mute(); 237 enabled = channelPtr->Mute();
251 } 238 }
252 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
253 "GetInputMute() => enabled = %d", (int)enabled);
254 return 0; 239 return 0;
255 } 240 }
256 241
257 int VoEVolumeControlImpl::GetSpeechInputLevel(unsigned int& level) { 242 int VoEVolumeControlImpl::GetSpeechInputLevel(unsigned int& level) {
258 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
259 "GetSpeechInputLevel()");
260
261 if (!_shared->statistics().Initialized()) { 243 if (!_shared->statistics().Initialized()) {
262 _shared->SetLastError(VE_NOT_INITED, kTraceError); 244 _shared->SetLastError(VE_NOT_INITED, kTraceError);
263 return -1; 245 return -1;
264 } 246 }
265 int8_t currentLevel = _shared->transmit_mixer()->AudioLevel(); 247 int8_t currentLevel = _shared->transmit_mixer()->AudioLevel();
266 level = static_cast<unsigned int>(currentLevel); 248 level = static_cast<unsigned int>(currentLevel);
267 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
268 "GetSpeechInputLevel() => %d", level);
269 return 0; 249 return 0;
270 } 250 }
271 251
272 int VoEVolumeControlImpl::GetSpeechOutputLevel(int channel, 252 int VoEVolumeControlImpl::GetSpeechOutputLevel(int channel,
273 unsigned int& level) { 253 unsigned int& level) {
274 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
275 "GetSpeechOutputLevel(channel=%d, level=?)", channel);
276
277 if (!_shared->statistics().Initialized()) { 254 if (!_shared->statistics().Initialized()) {
278 _shared->SetLastError(VE_NOT_INITED, kTraceError); 255 _shared->SetLastError(VE_NOT_INITED, kTraceError);
279 return -1; 256 return -1;
280 } 257 }
281 if (channel == -1) { 258 if (channel == -1) {
282 return _shared->output_mixer()->GetSpeechOutputLevel((uint32_t&)level); 259 return _shared->output_mixer()->GetSpeechOutputLevel((uint32_t&)level);
283 } else { 260 } else {
284 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 261 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
285 voe::Channel* channelPtr = ch.channel(); 262 voe::Channel* channelPtr = ch.channel();
286 if (channelPtr == NULL) { 263 if (channelPtr == NULL) {
287 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 264 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
288 "GetSpeechOutputLevel() failed to locate channel"); 265 "GetSpeechOutputLevel() failed to locate channel");
289 return -1; 266 return -1;
290 } 267 }
291 channelPtr->GetSpeechOutputLevel((uint32_t&)level); 268 channelPtr->GetSpeechOutputLevel((uint32_t&)level);
292 } 269 }
293 return 0; 270 return 0;
294 } 271 }
295 272
296 int VoEVolumeControlImpl::GetSpeechInputLevelFullRange(unsigned int& level) { 273 int VoEVolumeControlImpl::GetSpeechInputLevelFullRange(unsigned int& level) {
297 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
298 "GetSpeechInputLevelFullRange(level=?)");
299
300 if (!_shared->statistics().Initialized()) { 274 if (!_shared->statistics().Initialized()) {
301 _shared->SetLastError(VE_NOT_INITED, kTraceError); 275 _shared->SetLastError(VE_NOT_INITED, kTraceError);
302 return -1; 276 return -1;
303 } 277 }
304 int16_t currentLevel = _shared->transmit_mixer()->AudioLevelFullRange(); 278 int16_t currentLevel = _shared->transmit_mixer()->AudioLevelFullRange();
305 level = static_cast<unsigned int>(currentLevel); 279 level = static_cast<unsigned int>(currentLevel);
306 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
307 "GetSpeechInputLevelFullRange() => %d", level);
308 return 0; 280 return 0;
309 } 281 }
310 282
311 int VoEVolumeControlImpl::GetSpeechOutputLevelFullRange(int channel, 283 int VoEVolumeControlImpl::GetSpeechOutputLevelFullRange(int channel,
312 unsigned int& level) { 284 unsigned int& level) {
313 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
314 "GetSpeechOutputLevelFullRange(channel=%d, level=?)", channel);
315
316 if (!_shared->statistics().Initialized()) { 285 if (!_shared->statistics().Initialized()) {
317 _shared->SetLastError(VE_NOT_INITED, kTraceError); 286 _shared->SetLastError(VE_NOT_INITED, kTraceError);
318 return -1; 287 return -1;
319 } 288 }
320 if (channel == -1) { 289 if (channel == -1) {
321 return _shared->output_mixer()->GetSpeechOutputLevelFullRange( 290 return _shared->output_mixer()->GetSpeechOutputLevelFullRange(
322 (uint32_t&)level); 291 (uint32_t&)level);
323 } else { 292 } else {
324 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 293 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
325 voe::Channel* channelPtr = ch.channel(); 294 voe::Channel* channelPtr = ch.channel();
(...skipping 28 matching lines...) Expand all
354 _shared->SetLastError( 323 _shared->SetLastError(
355 VE_CHANNEL_NOT_VALID, kTraceError, 324 VE_CHANNEL_NOT_VALID, kTraceError,
356 "SetChannelOutputVolumeScaling() failed to locate channel"); 325 "SetChannelOutputVolumeScaling() failed to locate channel");
357 return -1; 326 return -1;
358 } 327 }
359 return channelPtr->SetChannelOutputVolumeScaling(scaling); 328 return channelPtr->SetChannelOutputVolumeScaling(scaling);
360 } 329 }
361 330
362 int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel, 331 int VoEVolumeControlImpl::GetChannelOutputVolumeScaling(int channel,
363 float& scaling) { 332 float& scaling) {
364 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
365 "GetChannelOutputVolumeScaling(channel=%d, scaling=?)", channel);
366 if (!_shared->statistics().Initialized()) { 333 if (!_shared->statistics().Initialized()) {
367 _shared->SetLastError(VE_NOT_INITED, kTraceError); 334 _shared->SetLastError(VE_NOT_INITED, kTraceError);
368 return -1; 335 return -1;
369 } 336 }
370 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 337 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
371 voe::Channel* channelPtr = ch.channel(); 338 voe::Channel* channelPtr = ch.channel();
372 if (channelPtr == NULL) { 339 if (channelPtr == NULL) {
373 _shared->SetLastError( 340 _shared->SetLastError(
374 VE_CHANNEL_NOT_VALID, kTraceError, 341 VE_CHANNEL_NOT_VALID, kTraceError,
375 "GetChannelOutputVolumeScaling() failed to locate channel"); 342 "GetChannelOutputVolumeScaling() failed to locate channel");
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 382 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
416 "SetOutputVolumePan() failed to locate channel"); 383 "SetOutputVolumePan() failed to locate channel");
417 return -1; 384 return -1;
418 } 385 }
419 return channelPtr->SetOutputVolumePan(left, right); 386 return channelPtr->SetOutputVolumePan(left, right);
420 } 387 }
421 388
422 int VoEVolumeControlImpl::GetOutputVolumePan(int channel, 389 int VoEVolumeControlImpl::GetOutputVolumePan(int channel,
423 float& left, 390 float& left,
424 float& right) { 391 float& right) {
425 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
426 "GetOutputVolumePan(channel=%d, left=?, right=?)", channel);
427
428 if (!_shared->statistics().Initialized()) { 392 if (!_shared->statistics().Initialized()) {
429 _shared->SetLastError(VE_NOT_INITED, kTraceError); 393 _shared->SetLastError(VE_NOT_INITED, kTraceError);
430 return -1; 394 return -1;
431 } 395 }
432 396
433 bool available(false); 397 bool available(false);
434 _shared->audio_device()->StereoPlayoutIsAvailable(&available); 398 _shared->audio_device()->StereoPlayoutIsAvailable(&available);
435 if (!available) { 399 if (!available) {
436 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError, 400 _shared->SetLastError(VE_FUNC_NO_STEREO, kTraceError,
437 "GetOutputVolumePan() stereo playout not supported"); 401 "GetOutputVolumePan() stereo playout not supported");
438 return -1; 402 return -1;
439 } 403 }
440 404
441 if (channel == -1) { 405 if (channel == -1) {
442 return _shared->output_mixer()->GetOutputVolumePan(left, right); 406 return _shared->output_mixer()->GetOutputVolumePan(left, right);
443 } 407 }
444 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 408 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
445 voe::Channel* channelPtr = ch.channel(); 409 voe::Channel* channelPtr = ch.channel();
446 if (channelPtr == NULL) { 410 if (channelPtr == NULL) {
447 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 411 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
448 "GetOutputVolumePan() failed to locate channel"); 412 "GetOutputVolumePan() failed to locate channel");
449 return -1; 413 return -1;
450 } 414 }
451 return channelPtr->GetOutputVolumePan(left, right); 415 return channelPtr->GetOutputVolumePan(left, right);
452 } 416 }
453 417
454 #endif // #ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API 418 #endif // #ifdef WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API
455 419
456 } // namespace webrtc 420 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/voice_engine/voe_video_sync_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698