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

Side by Side Diff: voice_engine/transmit_mixer.cc

Issue 3013033002: Remove VoEFile (Closed)
Patch Set: rebase Created 3 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 | « voice_engine/transmit_mixer.h ('k') | voice_engine/utility.h » ('j') | 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 "CallbackOnError(VE_TYPING_NOISE_OFF_WARNING)"); 60 "CallbackOnError(VE_TYPING_NOISE_OFF_WARNING)");
61 _voiceEngineObserverPtr->CallbackOnError( 61 _voiceEngineObserverPtr->CallbackOnError(
62 -1, 62 -1,
63 VE_TYPING_NOISE_OFF_WARNING); 63 VE_TYPING_NOISE_OFF_WARNING);
64 } 64 }
65 } 65 }
66 } 66 }
67 } 67 }
68 #endif // WEBRTC_VOICE_ENGINE_TYPING_DETECTION 68 #endif // WEBRTC_VOICE_ENGINE_TYPING_DETECTION
69 69
70 void TransmitMixer::PlayNotification(int32_t id,
71 uint32_t durationMs)
72 {
73 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
74 "TransmitMixer::PlayNotification(id=%d, durationMs=%d)",
75 id, durationMs);
76
77 // Not implement yet
78 }
79
80 void TransmitMixer::RecordNotification(int32_t id,
81 uint32_t durationMs)
82 {
83 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,-1),
84 "TransmitMixer::RecordNotification(id=%d, durationMs=%d)",
85 id, durationMs);
86
87 // Not implement yet
88 }
89
90 void TransmitMixer::PlayFileEnded(int32_t id)
91 {
92 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
93 "TransmitMixer::PlayFileEnded(id=%d)", id);
94
95 assert(id == _filePlayerId);
96
97 rtc::CritScope cs(&_critSect);
98
99 _filePlaying = false;
100 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
101 "TransmitMixer::PlayFileEnded() =>"
102 "file player module is shutdown");
103 }
104
105 void
106 TransmitMixer::RecordFileEnded(int32_t id)
107 {
108 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
109 "TransmitMixer::RecordFileEnded(id=%d)", id);
110
111 if (id == _fileRecorderId)
112 {
113 rtc::CritScope cs(&_critSect);
114 _fileRecording = false;
115 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
116 "TransmitMixer::RecordFileEnded() => fileRecorder module"
117 "is shutdown");
118 } else if (id == _fileCallRecorderId)
119 {
120 rtc::CritScope cs(&_critSect);
121 _fileCallRecording = false;
122 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
123 "TransmitMixer::RecordFileEnded() => fileCallRecorder"
124 "module is shutdown");
125 }
126 }
127
128 int32_t 70 int32_t
129 TransmitMixer::Create(TransmitMixer*& mixer, uint32_t instanceId) 71 TransmitMixer::Create(TransmitMixer*& mixer, uint32_t instanceId)
130 { 72 {
131 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, -1), 73 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, -1),
132 "TransmitMixer::Create(instanceId=%d)", instanceId); 74 "TransmitMixer::Create(instanceId=%d)", instanceId);
133 mixer = new TransmitMixer(instanceId); 75 mixer = new TransmitMixer(instanceId);
134 if (mixer == NULL) 76 if (mixer == NULL)
135 { 77 {
136 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, -1), 78 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, -1),
137 "TransmitMixer::Create() unable to allocate memory" 79 "TransmitMixer::Create() unable to allocate memory"
138 "for mixer"); 80 "for mixer");
139 return -1; 81 return -1;
140 } 82 }
141 return 0; 83 return 0;
142 } 84 }
143 85
144 void 86 void
145 TransmitMixer::Destroy(TransmitMixer*& mixer) 87 TransmitMixer::Destroy(TransmitMixer*& mixer)
146 { 88 {
147 if (mixer) 89 if (mixer)
148 { 90 {
149 delete mixer; 91 delete mixer;
150 mixer = NULL; 92 mixer = NULL;
151 } 93 }
152 } 94 }
153 95
154 TransmitMixer::TransmitMixer(uint32_t instanceId) : 96 TransmitMixer::TransmitMixer(uint32_t instanceId) :
155 // Avoid conflict with other channels by adding 1024 - 1026,
156 // won't use as much as 1024 channels.
157 _filePlayerId(instanceId + 1024),
158 _fileRecorderId(instanceId + 1025),
159 _fileCallRecorderId(instanceId + 1026),
160 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION 97 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
161 _monitorModule(this), 98 _monitorModule(this),
162 #endif 99 #endif
163 _instanceId(instanceId) 100 _instanceId(instanceId)
164 { 101 {
165 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), 102 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
166 "TransmitMixer::TransmitMixer() - ctor"); 103 "TransmitMixer::TransmitMixer() - ctor");
167 } 104 }
168 105
169 TransmitMixer::~TransmitMixer() 106 TransmitMixer::~TransmitMixer()
170 { 107 {
171 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), 108 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
172 "TransmitMixer::~TransmitMixer() - dtor"); 109 "TransmitMixer::~TransmitMixer() - dtor");
173 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION 110 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
174 if (_processThreadPtr) 111 if (_processThreadPtr)
175 _processThreadPtr->DeRegisterModule(&_monitorModule); 112 _processThreadPtr->DeRegisterModule(&_monitorModule);
176 #endif 113 #endif
177 {
178 rtc::CritScope cs(&_critSect);
179 if (file_recorder_) {
180 file_recorder_->RegisterModuleFileCallback(NULL);
181 file_recorder_->StopRecording();
182 }
183 if (file_call_recorder_) {
184 file_call_recorder_->RegisterModuleFileCallback(NULL);
185 file_call_recorder_->StopRecording();
186 }
187 if (file_player_) {
188 file_player_->RegisterModuleFileCallback(NULL);
189 file_player_->StopPlayingFile();
190 }
191 }
192 } 114 }
193 115
194 int32_t 116 int32_t
195 TransmitMixer::SetEngineInformation(ProcessThread& processThread, 117 TransmitMixer::SetEngineInformation(ProcessThread& processThread,
196 Statistics& engineStatistics, 118 Statistics& engineStatistics,
197 ChannelManager& channelManager) 119 ChannelManager& channelManager)
198 { 120 {
199 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 121 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
200 "TransmitMixer::SetEngineInformation()"); 122 "TransmitMixer::SetEngineInformation()");
201 123
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 210
289 if (swap_stereo_channels_ && stereo_codec_) 211 if (swap_stereo_channels_ && stereo_codec_)
290 // Only bother swapping if we're using a stereo codec. 212 // Only bother swapping if we're using a stereo codec.
291 AudioFrameOperations::SwapStereoChannels(&_audioFrame); 213 AudioFrameOperations::SwapStereoChannels(&_audioFrame);
292 214
293 // --- Annoying typing detection (utilizes the APM/VAD decision) 215 // --- Annoying typing detection (utilizes the APM/VAD decision)
294 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION 216 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
295 TypingDetection(keyPressed); 217 TypingDetection(keyPressed);
296 #endif 218 #endif
297 219
298 // --- Mix with file (does not affect the mixing frequency)
299 if (_filePlaying)
300 {
301 MixOrReplaceAudioWithFile(_audioFrame.sample_rate_hz_);
302 }
303
304 // --- Record to file
305 bool file_recording = false;
306 {
307 rtc::CritScope cs(&_critSect);
308 file_recording = _fileRecording;
309 }
310 if (file_recording)
311 {
312 RecordAudioToFile(_audioFrame.sample_rate_hz_);
313 }
314
315 // --- Measure audio level of speech after all processing. 220 // --- Measure audio level of speech after all processing.
316 double sample_duration = static_cast<double>(nSamples) / samplesPerSec; 221 double sample_duration = static_cast<double>(nSamples) / samplesPerSec;
317 _audioLevel.ComputeLevel(_audioFrame, sample_duration); 222 _audioLevel.ComputeLevel(_audioFrame, sample_duration);
318 223
319 return 0; 224 return 0;
320 } 225 }
321 226
322 void TransmitMixer::ProcessAndEncodeAudio() { 227 void TransmitMixer::ProcessAndEncodeAudio() {
323 RTC_DCHECK_GT(_audioFrame.samples_per_channel_, 0); 228 RTC_DCHECK_GT(_audioFrame.samples_per_channel_, 0);
324 for (ChannelManager::Iterator it(_channelManagerPtr); it.IsValid(); 229 for (ChannelManager::Iterator it(_channelManagerPtr); it.IsValid();
(...skipping 12 matching lines...) Expand all
337 242
338 int32_t 243 int32_t
339 TransmitMixer::StopSend() 244 TransmitMixer::StopSend()
340 { 245 {
341 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 246 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
342 "TransmitMixer::StopSend()"); 247 "TransmitMixer::StopSend()");
343 _audioLevel.Clear(); 248 _audioLevel.Clear();
344 return 0; 249 return 0;
345 } 250 }
346 251
347 int TransmitMixer::StartPlayingFileAsMicrophone(const char* fileName,
348 bool loop,
349 FileFormats format,
350 int startPosition,
351 float volumeScaling,
352 int stopPosition,
353 const CodecInst* codecInst)
354 {
355 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
356 "TransmitMixer::StartPlayingFileAsMicrophone("
357 "fileNameUTF8[]=%s,loop=%d, format=%d, volumeScaling=%5.3f,"
358 " startPosition=%d, stopPosition=%d)", fileName, loop,
359 format, volumeScaling, startPosition, stopPosition);
360
361 if (_filePlaying)
362 {
363 _engineStatisticsPtr->SetLastError(
364 VE_ALREADY_PLAYING, kTraceWarning,
365 "StartPlayingFileAsMicrophone() is already playing");
366 return 0;
367 }
368
369 rtc::CritScope cs(&_critSect);
370
371 // Destroy the old instance
372 if (file_player_) {
373 file_player_->RegisterModuleFileCallback(NULL);
374 file_player_.reset();
375 }
376
377 // Dynamically create the instance
378 file_player_ =
379 FilePlayer::CreateFilePlayer(_filePlayerId, (const FileFormats)format);
380
381 if (!file_player_) {
382 _engineStatisticsPtr->SetLastError(
383 VE_INVALID_ARGUMENT, kTraceError,
384 "StartPlayingFileAsMicrophone() filePlayer format isnot correct");
385 return -1;
386 }
387
388 const uint32_t notificationTime(0);
389
390 if (file_player_->StartPlayingFile(
391 fileName, loop, startPosition, volumeScaling, notificationTime,
392 stopPosition, (const CodecInst*)codecInst) != 0) {
393 _engineStatisticsPtr->SetLastError(
394 VE_BAD_FILE, kTraceError,
395 "StartPlayingFile() failed to start file playout");
396 file_player_->StopPlayingFile();
397 file_player_.reset();
398 return -1;
399 }
400
401 file_player_->RegisterModuleFileCallback(this);
402 _filePlaying = true;
403
404 return 0;
405 }
406
407 int TransmitMixer::StartPlayingFileAsMicrophone(InStream* stream,
408 FileFormats format,
409 int startPosition,
410 float volumeScaling,
411 int stopPosition,
412 const CodecInst* codecInst)
413 {
414 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1),
415 "TransmitMixer::StartPlayingFileAsMicrophone(format=%d,"
416 " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)",
417 format, volumeScaling, startPosition, stopPosition);
418
419 if (stream == NULL)
420 {
421 _engineStatisticsPtr->SetLastError(
422 VE_BAD_FILE, kTraceError,
423 "StartPlayingFileAsMicrophone() NULL as input stream");
424 return -1;
425 }
426
427 if (_filePlaying)
428 {
429 _engineStatisticsPtr->SetLastError(
430 VE_ALREADY_PLAYING, kTraceWarning,
431 "StartPlayingFileAsMicrophone() is already playing");
432 return 0;
433 }
434
435 rtc::CritScope cs(&_critSect);
436
437 // Destroy the old instance
438 if (file_player_) {
439 file_player_->RegisterModuleFileCallback(NULL);
440 file_player_.reset();
441 }
442
443 // Dynamically create the instance
444 file_player_ =
445 FilePlayer::CreateFilePlayer(_filePlayerId, (const FileFormats)format);
446
447 if (!file_player_) {
448 _engineStatisticsPtr->SetLastError(
449 VE_INVALID_ARGUMENT, kTraceWarning,
450 "StartPlayingFileAsMicrophone() filePlayer format isnot correct");
451 return -1;
452 }
453
454 const uint32_t notificationTime(0);
455
456 if (file_player_->StartPlayingFile(stream, startPosition, volumeScaling,
457 notificationTime, stopPosition,
458 (const CodecInst*)codecInst) != 0) {
459 _engineStatisticsPtr->SetLastError(
460 VE_BAD_FILE, kTraceError,
461 "StartPlayingFile() failed to start file playout");
462 file_player_->StopPlayingFile();
463 file_player_.reset();
464 return -1;
465 }
466 file_player_->RegisterModuleFileCallback(this);
467 _filePlaying = true;
468
469 return 0;
470 }
471
472 int TransmitMixer::StopPlayingFileAsMicrophone()
473 {
474 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1),
475 "TransmitMixer::StopPlayingFileAsMicrophone()");
476
477 if (!_filePlaying)
478 {
479 return 0;
480 }
481
482 rtc::CritScope cs(&_critSect);
483
484 if (file_player_->StopPlayingFile() != 0) {
485 _engineStatisticsPtr->SetLastError(
486 VE_CANNOT_STOP_PLAYOUT, kTraceError,
487 "StopPlayingFile() couldnot stop playing file");
488 return -1;
489 }
490
491 file_player_->RegisterModuleFileCallback(NULL);
492 file_player_.reset();
493 _filePlaying = false;
494
495 return 0;
496 }
497
498 int TransmitMixer::IsPlayingFileAsMicrophone() const
499 {
500 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
501 "TransmitMixer::IsPlayingFileAsMicrophone()");
502 return _filePlaying;
503 }
504
505 int TransmitMixer::StartRecordingMicrophone(const char* fileName,
506 const CodecInst* codecInst)
507 {
508 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
509 "TransmitMixer::StartRecordingMicrophone(fileName=%s)",
510 fileName);
511
512 rtc::CritScope cs(&_critSect);
513
514 if (_fileRecording)
515 {
516 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
517 "StartRecordingMicrophone() is already recording");
518 return 0;
519 }
520
521 FileFormats format;
522 const uint32_t notificationTime(0); // Not supported in VoE
523 CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 };
524
525 if (codecInst != NULL && codecInst->channels > 2)
526 {
527 _engineStatisticsPtr->SetLastError(
528 VE_BAD_ARGUMENT, kTraceError,
529 "StartRecordingMicrophone() invalid compression");
530 return (-1);
531 }
532 if (codecInst == NULL)
533 {
534 format = kFileFormatPcm16kHzFile;
535 codecInst = &dummyCodec;
536 } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) ||
537 (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) ||
538 (STR_CASE_CMP(codecInst->plname,"PCMA") == 0))
539 {
540 format = kFileFormatWavFile;
541 } else
542 {
543 format = kFileFormatCompressedFile;
544 }
545
546 // Destroy the old instance
547 if (file_recorder_) {
548 file_recorder_->RegisterModuleFileCallback(NULL);
549 file_recorder_.reset();
550 }
551
552 file_recorder_ = FileRecorder::CreateFileRecorder(
553 _fileRecorderId, (const FileFormats)format);
554 if (!file_recorder_) {
555 _engineStatisticsPtr->SetLastError(
556 VE_INVALID_ARGUMENT, kTraceError,
557 "StartRecordingMicrophone() fileRecorder format isnot correct");
558 return -1;
559 }
560
561 if (file_recorder_->StartRecordingAudioFile(
562 fileName, (const CodecInst&)*codecInst, notificationTime) != 0) {
563 _engineStatisticsPtr->SetLastError(
564 VE_BAD_FILE, kTraceError,
565 "StartRecordingAudioFile() failed to start file recording");
566 file_recorder_->StopRecording();
567 file_recorder_.reset();
568 return -1;
569 }
570 file_recorder_->RegisterModuleFileCallback(this);
571 _fileRecording = true;
572
573 return 0;
574 }
575
576 int TransmitMixer::StartRecordingMicrophone(OutStream* stream,
577 const CodecInst* codecInst)
578 {
579 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
580 "TransmitMixer::StartRecordingMicrophone()");
581
582 rtc::CritScope cs(&_critSect);
583
584 if (_fileRecording)
585 {
586 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
587 "StartRecordingMicrophone() is already recording");
588 return 0;
589 }
590
591 FileFormats format;
592 const uint32_t notificationTime(0); // Not supported in VoE
593 CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 };
594
595 if (codecInst != NULL && codecInst->channels != 1)
596 {
597 _engineStatisticsPtr->SetLastError(
598 VE_BAD_ARGUMENT, kTraceError,
599 "StartRecordingMicrophone() invalid compression");
600 return (-1);
601 }
602 if (codecInst == NULL)
603 {
604 format = kFileFormatPcm16kHzFile;
605 codecInst = &dummyCodec;
606 } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) ||
607 (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) ||
608 (STR_CASE_CMP(codecInst->plname,"PCMA") == 0))
609 {
610 format = kFileFormatWavFile;
611 } else
612 {
613 format = kFileFormatCompressedFile;
614 }
615
616 // Destroy the old instance
617 if (file_recorder_) {
618 file_recorder_->RegisterModuleFileCallback(NULL);
619 file_recorder_.reset();
620 }
621
622 file_recorder_ = FileRecorder::CreateFileRecorder(
623 _fileRecorderId, (const FileFormats)format);
624 if (!file_recorder_) {
625 _engineStatisticsPtr->SetLastError(
626 VE_INVALID_ARGUMENT, kTraceError,
627 "StartRecordingMicrophone() fileRecorder format isnot correct");
628 return -1;
629 }
630
631 if (file_recorder_->StartRecordingAudioFile(stream, *codecInst,
632 notificationTime) != 0) {
633 _engineStatisticsPtr->SetLastError(
634 VE_BAD_FILE, kTraceError,
635 "StartRecordingAudioFile() failed to start file recording");
636 file_recorder_->StopRecording();
637 file_recorder_.reset();
638 return -1;
639 }
640
641 file_recorder_->RegisterModuleFileCallback(this);
642 _fileRecording = true;
643
644 return 0;
645 }
646
647
648 int TransmitMixer::StopRecordingMicrophone()
649 {
650 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
651 "TransmitMixer::StopRecordingMicrophone()");
652
653 rtc::CritScope cs(&_critSect);
654
655 if (!_fileRecording)
656 {
657 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
658 "StopRecordingMicrophone() isnot recording");
659 return 0;
660 }
661
662 if (file_recorder_->StopRecording() != 0) {
663 _engineStatisticsPtr->SetLastError(
664 VE_STOP_RECORDING_FAILED, kTraceError,
665 "StopRecording(), could not stop recording");
666 return -1;
667 }
668 file_recorder_->RegisterModuleFileCallback(NULL);
669 file_recorder_.reset();
670 _fileRecording = false;
671
672 return 0;
673 }
674
675 int TransmitMixer::StartRecordingCall(const char* fileName,
676 const CodecInst* codecInst)
677 {
678 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
679 "TransmitMixer::StartRecordingCall(fileName=%s)", fileName);
680
681 if (_fileCallRecording)
682 {
683 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
684 "StartRecordingCall() is already recording");
685 return 0;
686 }
687
688 FileFormats format;
689 const uint32_t notificationTime(0); // Not supported in VoE
690 CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 };
691
692 if (codecInst != NULL && codecInst->channels != 1)
693 {
694 _engineStatisticsPtr->SetLastError(
695 VE_BAD_ARGUMENT, kTraceError,
696 "StartRecordingCall() invalid compression");
697 return (-1);
698 }
699 if (codecInst == NULL)
700 {
701 format = kFileFormatPcm16kHzFile;
702 codecInst = &dummyCodec;
703 } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) ||
704 (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) ||
705 (STR_CASE_CMP(codecInst->plname,"PCMA") == 0))
706 {
707 format = kFileFormatWavFile;
708 } else
709 {
710 format = kFileFormatCompressedFile;
711 }
712
713 rtc::CritScope cs(&_critSect);
714
715 // Destroy the old instance
716 if (file_call_recorder_) {
717 file_call_recorder_->RegisterModuleFileCallback(NULL);
718 file_call_recorder_.reset();
719 }
720
721 file_call_recorder_ = FileRecorder::CreateFileRecorder(
722 _fileCallRecorderId, (const FileFormats)format);
723 if (!file_call_recorder_) {
724 _engineStatisticsPtr->SetLastError(
725 VE_INVALID_ARGUMENT, kTraceError,
726 "StartRecordingCall() fileRecorder format isnot correct");
727 return -1;
728 }
729
730 if (file_call_recorder_->StartRecordingAudioFile(
731 fileName, (const CodecInst&)*codecInst, notificationTime) != 0) {
732 _engineStatisticsPtr->SetLastError(
733 VE_BAD_FILE, kTraceError,
734 "StartRecordingAudioFile() failed to start file recording");
735 file_call_recorder_->StopRecording();
736 file_call_recorder_.reset();
737 return -1;
738 }
739 file_call_recorder_->RegisterModuleFileCallback(this);
740 _fileCallRecording = true;
741
742 return 0;
743 }
744
745 int TransmitMixer::StartRecordingCall(OutStream* stream,
746 const CodecInst* codecInst)
747 {
748 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
749 "TransmitMixer::StartRecordingCall()");
750
751 if (_fileCallRecording)
752 {
753 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
754 "StartRecordingCall() is already recording");
755 return 0;
756 }
757
758 FileFormats format;
759 const uint32_t notificationTime(0); // Not supported in VoE
760 CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 };
761
762 if (codecInst != NULL && codecInst->channels != 1)
763 {
764 _engineStatisticsPtr->SetLastError(
765 VE_BAD_ARGUMENT, kTraceError,
766 "StartRecordingCall() invalid compression");
767 return (-1);
768 }
769 if (codecInst == NULL)
770 {
771 format = kFileFormatPcm16kHzFile;
772 codecInst = &dummyCodec;
773 } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) ||
774 (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) ||
775 (STR_CASE_CMP(codecInst->plname,"PCMA") == 0))
776 {
777 format = kFileFormatWavFile;
778 } else
779 {
780 format = kFileFormatCompressedFile;
781 }
782
783 rtc::CritScope cs(&_critSect);
784
785 // Destroy the old instance
786 if (file_call_recorder_) {
787 file_call_recorder_->RegisterModuleFileCallback(NULL);
788 file_call_recorder_.reset();
789 }
790
791 file_call_recorder_ = FileRecorder::CreateFileRecorder(
792 _fileCallRecorderId, (const FileFormats)format);
793 if (!file_call_recorder_) {
794 _engineStatisticsPtr->SetLastError(
795 VE_INVALID_ARGUMENT, kTraceError,
796 "StartRecordingCall() fileRecorder format isnot correct");
797 return -1;
798 }
799
800 if (file_call_recorder_->StartRecordingAudioFile(stream, *codecInst,
801 notificationTime) != 0) {
802 _engineStatisticsPtr->SetLastError(
803 VE_BAD_FILE, kTraceError,
804 "StartRecordingAudioFile() failed to start file recording");
805 file_call_recorder_->StopRecording();
806 file_call_recorder_.reset();
807 return -1;
808 }
809
810 file_call_recorder_->RegisterModuleFileCallback(this);
811 _fileCallRecording = true;
812
813 return 0;
814 }
815
816 int TransmitMixer::StopRecordingCall()
817 {
818 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
819 "TransmitMixer::StopRecordingCall()");
820
821 if (!_fileCallRecording)
822 {
823 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
824 "StopRecordingCall() file isnot recording");
825 return -1;
826 }
827
828 rtc::CritScope cs(&_critSect);
829
830 if (file_call_recorder_->StopRecording() != 0) {
831 _engineStatisticsPtr->SetLastError(
832 VE_STOP_RECORDING_FAILED, kTraceError,
833 "StopRecording(), could not stop recording");
834 return -1;
835 }
836
837 file_call_recorder_->RegisterModuleFileCallback(NULL);
838 file_call_recorder_.reset();
839 _fileCallRecording = false;
840
841 return 0;
842 }
843
844 void
845 TransmitMixer::SetMixWithMicStatus(bool mix)
846 {
847 _mixFileWithMicrophone = mix;
848 }
849
850 int8_t TransmitMixer::AudioLevel() const 252 int8_t TransmitMixer::AudioLevel() const
851 { 253 {
852 // Speech + file level [0,9] 254 // Speech + file level [0,9]
853 return _audioLevel.Level(); 255 return _audioLevel.Level();
854 } 256 }
855 257
856 int16_t TransmitMixer::AudioLevelFullRange() const 258 int16_t TransmitMixer::AudioLevelFullRange() const
857 { 259 {
858 // Speech + file level [0,32767] 260 // Speech + file level [0,32767]
859 return _audioLevel.LevelFullRange(); 261 return _audioLevel.LevelFullRange();
860 } 262 }
861 263
862 double TransmitMixer::GetTotalInputEnergy() const { 264 double TransmitMixer::GetTotalInputEnergy() const {
863 return _audioLevel.TotalEnergy(); 265 return _audioLevel.TotalEnergy();
864 } 266 }
865 267
866 double TransmitMixer::GetTotalInputDuration() const { 268 double TransmitMixer::GetTotalInputDuration() const {
867 return _audioLevel.TotalDuration(); 269 return _audioLevel.TotalDuration();
868 } 270 }
869 271
870 bool TransmitMixer::IsRecordingCall()
871 {
872 return _fileCallRecording;
873 }
874
875 bool TransmitMixer::IsRecordingMic()
876 {
877 rtc::CritScope cs(&_critSect);
878 return _fileRecording;
879 }
880
881 void TransmitMixer::GenerateAudioFrame(const int16_t* audio, 272 void TransmitMixer::GenerateAudioFrame(const int16_t* audio,
882 size_t samples_per_channel, 273 size_t samples_per_channel,
883 size_t num_channels, 274 size_t num_channels,
884 int sample_rate_hz) { 275 int sample_rate_hz) {
885 int codec_rate; 276 int codec_rate;
886 size_t num_codec_channels; 277 size_t num_codec_channels;
887 GetSendCodecInfo(&codec_rate, &num_codec_channels); 278 GetSendCodecInfo(&codec_rate, &num_codec_channels);
888 stereo_codec_ = num_codec_channels == 2; 279 stereo_codec_ = num_codec_channels == 2;
889 280
890 // We want to process at the lowest rate possible without losing information. 281 // We want to process at the lowest rate possible without losing information.
891 // Choose the lowest native rate at least equal to the input and codec rates. 282 // Choose the lowest native rate at least equal to the input and codec rates.
892 const int min_processing_rate = std::min(sample_rate_hz, codec_rate); 283 const int min_processing_rate = std::min(sample_rate_hz, codec_rate);
893 for (size_t i = 0; i < AudioProcessing::kNumNativeSampleRates; ++i) { 284 for (size_t i = 0; i < AudioProcessing::kNumNativeSampleRates; ++i) {
894 _audioFrame.sample_rate_hz_ = AudioProcessing::kNativeSampleRatesHz[i]; 285 _audioFrame.sample_rate_hz_ = AudioProcessing::kNativeSampleRatesHz[i];
895 if (_audioFrame.sample_rate_hz_ >= min_processing_rate) { 286 if (_audioFrame.sample_rate_hz_ >= min_processing_rate) {
896 break; 287 break;
897 } 288 }
898 } 289 }
899 _audioFrame.num_channels_ = std::min(num_channels, num_codec_channels); 290 _audioFrame.num_channels_ = std::min(num_channels, num_codec_channels);
900 RemixAndResample(audio, samples_per_channel, num_channels, sample_rate_hz, 291 RemixAndResample(audio, samples_per_channel, num_channels, sample_rate_hz,
901 &resampler_, &_audioFrame); 292 &resampler_, &_audioFrame);
902 } 293 }
903 294
904 int32_t TransmitMixer::RecordAudioToFile(
905 uint32_t mixingFrequency)
906 {
907 rtc::CritScope cs(&_critSect);
908 if (!file_recorder_) {
909 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
910 "TransmitMixer::RecordAudioToFile() filerecorder doesnot"
911 "exist");
912 return -1;
913 }
914
915 if (file_recorder_->RecordAudioToFile(_audioFrame) != 0) {
916 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
917 "TransmitMixer::RecordAudioToFile() file recording"
918 "failed");
919 return -1;
920 }
921
922 return 0;
923 }
924
925 int32_t TransmitMixer::MixOrReplaceAudioWithFile(
926 int mixingFrequency)
927 {
928 std::unique_ptr<int16_t[]> fileBuffer(new int16_t[640]);
929
930 size_t fileSamples(0);
931 {
932 rtc::CritScope cs(&_critSect);
933 if (!file_player_) {
934 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
935 "TransmitMixer::MixOrReplaceAudioWithFile()"
936 "fileplayer doesnot exist");
937 return -1;
938 }
939
940 if (file_player_->Get10msAudioFromFile(fileBuffer.get(), &fileSamples,
941 mixingFrequency) == -1) {
942 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
943 "TransmitMixer::MixOrReplaceAudioWithFile() file"
944 " mixing failed");
945 return -1;
946 }
947 }
948
949 assert(_audioFrame.samples_per_channel_ == fileSamples);
950
951 if (_mixFileWithMicrophone)
952 {
953 // Currently file stream is always mono.
954 // TODO(xians): Change the code when FilePlayer supports real stereo.
955 MixWithSat(_audioFrame.mutable_data(),
956 _audioFrame.num_channels_,
957 fileBuffer.get(),
958 1,
959 fileSamples);
960 } else
961 {
962 // Replace ACM audio with file.
963 // Currently file stream is always mono.
964 // TODO(xians): Change the code when FilePlayer supports real stereo.
965 _audioFrame.UpdateFrame(-1,
966 0xFFFFFFFF,
967 fileBuffer.get(),
968 fileSamples,
969 mixingFrequency,
970 AudioFrame::kNormalSpeech,
971 AudioFrame::kVadUnknown,
972 1);
973 }
974 return 0;
975 }
976
977 void TransmitMixer::ProcessAudio(int delay_ms, int clock_drift, 295 void TransmitMixer::ProcessAudio(int delay_ms, int clock_drift,
978 int current_mic_level, bool key_pressed) { 296 int current_mic_level, bool key_pressed) {
979 if (audioproc_->set_stream_delay_ms(delay_ms) != 0) { 297 if (audioproc_->set_stream_delay_ms(delay_ms) != 0) {
980 // Silently ignore this failure to avoid flooding the logs. 298 // Silently ignore this failure to avoid flooding the logs.
981 } 299 }
982 300
983 GainControl* agc = audioproc_->gain_control(); 301 GainControl* agc = audioproc_->gain_control();
984 if (agc->set_stream_analog_level(current_mic_level) != 0) { 302 if (agc->set_stream_analog_level(current_mic_level) != 0) {
985 LOG(LS_ERROR) << "set_stream_analog_level failed: current_mic_level = " 303 LOG(LS_ERROR) << "set_stream_analog_level failed: current_mic_level = "
986 << current_mic_level; 304 << current_mic_level;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 void TransmitMixer::EnableStereoChannelSwapping(bool enable) { 350 void TransmitMixer::EnableStereoChannelSwapping(bool enable) {
1033 swap_stereo_channels_ = enable; 351 swap_stereo_channels_ = enable;
1034 } 352 }
1035 353
1036 bool TransmitMixer::IsStereoChannelSwappingEnabled() { 354 bool TransmitMixer::IsStereoChannelSwappingEnabled() {
1037 return swap_stereo_channels_; 355 return swap_stereo_channels_;
1038 } 356 }
1039 357
1040 } // namespace voe 358 } // namespace voe
1041 } // namespace webrtc 359 } // namespace webrtc
OLDNEW
« no previous file with comments | « voice_engine/transmit_mixer.h ('k') | voice_engine/utility.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698