OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 static const int kTimePerFrameMs = 10; | 47 static const int kTimePerFrameMs = 10; |
48 static const uint8_t kNumberOfChannels = 1; | 48 static const uint8_t kNumberOfChannels = 1; |
49 static const int kSamplesPerSecond = 44000; | 49 static const int kSamplesPerSecond = 44000; |
50 static const int kTotalDelayMs = 0; | 50 static const int kTotalDelayMs = 0; |
51 static const int kClockDriftMs = 0; | 51 static const int kClockDriftMs = 0; |
52 static const uint32_t kMaxVolume = 14392; | 52 static const uint32_t kMaxVolume = 14392; |
53 | 53 |
54 enum { | 54 enum { |
55 MSG_START_PROCESS, | 55 MSG_START_PROCESS, |
56 MSG_RUN_PROCESS, | 56 MSG_RUN_PROCESS, |
57 MSG_STOP_PROCESS, | |
58 }; | 57 }; |
59 | 58 |
60 FakeAudioCaptureModule::FakeAudioCaptureModule( | 59 FakeAudioCaptureModule::FakeAudioCaptureModule() |
61 rtc::Thread* process_thread) | |
62 : last_process_time_ms_(0), | 60 : last_process_time_ms_(0), |
63 audio_callback_(NULL), | 61 audio_callback_(nullptr), |
64 recording_(false), | 62 recording_(false), |
65 playing_(false), | 63 playing_(false), |
66 play_is_initialized_(false), | 64 play_is_initialized_(false), |
67 rec_is_initialized_(false), | 65 rec_is_initialized_(false), |
68 current_mic_level_(kMaxVolume), | 66 current_mic_level_(kMaxVolume), |
69 started_(false), | 67 started_(false), |
70 next_frame_time_(0), | 68 next_frame_time_(0), |
71 process_thread_(process_thread), | |
72 frames_received_(0) { | 69 frames_received_(0) { |
73 } | 70 } |
74 | 71 |
75 FakeAudioCaptureModule::~FakeAudioCaptureModule() { | 72 FakeAudioCaptureModule::~FakeAudioCaptureModule() { |
76 // Ensure that thread stops calling ProcessFrame(). | 73 if (process_thread_) { |
77 process_thread_->Send(this, MSG_STOP_PROCESS); | 74 process_thread_->Stop(); |
| 75 } |
78 } | 76 } |
79 | 77 |
80 rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create( | 78 rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() { |
81 rtc::Thread* process_thread) { | |
82 if (process_thread == NULL) return NULL; | |
83 | |
84 rtc::scoped_refptr<FakeAudioCaptureModule> capture_module( | 79 rtc::scoped_refptr<FakeAudioCaptureModule> capture_module( |
85 new rtc::RefCountedObject<FakeAudioCaptureModule>(process_thread)); | 80 new rtc::RefCountedObject<FakeAudioCaptureModule>()); |
86 if (!capture_module->Initialize()) { | 81 if (!capture_module->Initialize()) { |
87 return NULL; | 82 return nullptr; |
88 } | 83 } |
89 return capture_module; | 84 return capture_module; |
90 } | 85 } |
91 | 86 |
92 int FakeAudioCaptureModule::frames_received() const { | 87 int FakeAudioCaptureModule::frames_received() const { |
93 rtc::CritScope cs(&crit_); | 88 rtc::CritScope cs(&crit_); |
94 return frames_received_; | 89 return frames_received_; |
95 } | 90 } |
96 | 91 |
97 int64_t FakeAudioCaptureModule::TimeUntilNextProcess() { | 92 int64_t FakeAudioCaptureModule::TimeUntilNextProcess() { |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 } | 589 } |
595 | 590 |
596 void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) { | 591 void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) { |
597 switch (msg->message_id) { | 592 switch (msg->message_id) { |
598 case MSG_START_PROCESS: | 593 case MSG_START_PROCESS: |
599 StartProcessP(); | 594 StartProcessP(); |
600 break; | 595 break; |
601 case MSG_RUN_PROCESS: | 596 case MSG_RUN_PROCESS: |
602 ProcessFrameP(); | 597 ProcessFrameP(); |
603 break; | 598 break; |
604 case MSG_STOP_PROCESS: | |
605 StopProcessP(); | |
606 break; | |
607 default: | 599 default: |
608 // All existing messages should be caught. Getting here should never | 600 // All existing messages should be caught. Getting here should never |
609 // happen. | 601 // happen. |
610 ASSERT(false); | 602 ASSERT(false); |
611 } | 603 } |
612 } | 604 } |
613 | 605 |
614 bool FakeAudioCaptureModule::Initialize() { | 606 bool FakeAudioCaptureModule::Initialize() { |
615 // Set the send buffer samples high enough that it would not occur on the | 607 // Set the send buffer samples high enough that it would not occur on the |
616 // remote side unless a packet containing a sample of that magnitude has been | 608 // remote side unless a packet containing a sample of that magnitude has been |
(...skipping 26 matching lines...) Expand all Loading... |
643 } | 635 } |
644 return false; | 636 return false; |
645 } | 637 } |
646 | 638 |
647 bool FakeAudioCaptureModule::ShouldStartProcessing() { | 639 bool FakeAudioCaptureModule::ShouldStartProcessing() { |
648 return recording_ || playing_; | 640 return recording_ || playing_; |
649 } | 641 } |
650 | 642 |
651 void FakeAudioCaptureModule::UpdateProcessing(bool start) { | 643 void FakeAudioCaptureModule::UpdateProcessing(bool start) { |
652 if (start) { | 644 if (start) { |
| 645 if (!process_thread_) { |
| 646 process_thread_.reset(new rtc::Thread()); |
| 647 process_thread_->Start(); |
| 648 } |
653 process_thread_->Post(this, MSG_START_PROCESS); | 649 process_thread_->Post(this, MSG_START_PROCESS); |
654 } else { | 650 } else { |
655 process_thread_->Send(this, MSG_STOP_PROCESS); | 651 if (process_thread_) { |
| 652 process_thread_->Stop(); |
| 653 process_thread_.reset(nullptr); |
| 654 } |
| 655 started_ = false; |
656 } | 656 } |
657 } | 657 } |
658 | 658 |
659 void FakeAudioCaptureModule::StartProcessP() { | 659 void FakeAudioCaptureModule::StartProcessP() { |
660 ASSERT(rtc::Thread::Current() == process_thread_); | 660 ASSERT(process_thread_->IsCurrent()); |
661 if (started_) { | 661 if (started_) { |
662 // Already started. | 662 // Already started. |
663 return; | 663 return; |
664 } | 664 } |
665 ProcessFrameP(); | 665 ProcessFrameP(); |
666 } | 666 } |
667 | 667 |
668 void FakeAudioCaptureModule::ProcessFrameP() { | 668 void FakeAudioCaptureModule::ProcessFrameP() { |
669 ASSERT(rtc::Thread::Current() == process_thread_); | 669 ASSERT(process_thread_->IsCurrent()); |
670 if (!started_) { | 670 if (!started_) { |
671 next_frame_time_ = rtc::Time(); | 671 next_frame_time_ = rtc::Time(); |
672 started_ = true; | 672 started_ = true; |
673 } | 673 } |
674 | 674 |
675 bool playing; | |
676 bool recording; | |
677 { | 675 { |
678 rtc::CritScope cs(&crit_); | 676 rtc::CritScope cs(&crit_); |
679 playing = playing_; | 677 // Receive and send frames every kTimePerFrameMs. |
680 recording = recording_; | 678 if (playing_) { |
681 } | 679 ReceiveFrameP(); |
682 | 680 } |
683 // Receive and send frames every kTimePerFrameMs. | 681 if (recording_) { |
684 if (playing) { | 682 SendFrameP(); |
685 ReceiveFrameP(); | 683 } |
686 } | |
687 if (recording) { | |
688 SendFrameP(); | |
689 } | 684 } |
690 | 685 |
691 next_frame_time_ += kTimePerFrameMs; | 686 next_frame_time_ += kTimePerFrameMs; |
692 const uint32 current_time = rtc::Time(); | 687 const uint32 current_time = rtc::Time(); |
693 const uint32 wait_time = (next_frame_time_ > current_time) ? | 688 const uint32 wait_time = (next_frame_time_ > current_time) ? |
694 next_frame_time_ - current_time : 0; | 689 next_frame_time_ - current_time : 0; |
695 process_thread_->PostDelayed(wait_time, this, MSG_RUN_PROCESS); | 690 process_thread_->PostDelayed(wait_time, this, MSG_RUN_PROCESS); |
696 } | 691 } |
697 | 692 |
698 void FakeAudioCaptureModule::ReceiveFrameP() { | 693 void FakeAudioCaptureModule::ReceiveFrameP() { |
699 ASSERT(rtc::Thread::Current() == process_thread_); | 694 ASSERT(process_thread_->IsCurrent()); |
700 { | 695 { |
701 rtc::CritScope cs(&crit_callback_); | 696 rtc::CritScope cs(&crit_callback_); |
702 if (!audio_callback_) { | 697 if (!audio_callback_) { |
703 return; | 698 return; |
704 } | 699 } |
705 ResetRecBuffer(); | 700 ResetRecBuffer(); |
706 uint32_t nSamplesOut = 0; | 701 uint32_t nSamplesOut = 0; |
707 int64_t elapsed_time_ms = 0; | 702 int64_t elapsed_time_ms = 0; |
708 int64_t ntp_time_ms = 0; | 703 int64_t ntp_time_ms = 0; |
709 if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample, | 704 if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample, |
(...skipping 10 matching lines...) Expand all Loading... |
720 // have the same or greater magnitude somewhere in the frame, an actual frame | 715 // have the same or greater magnitude somewhere in the frame, an actual frame |
721 // has been received from the remote side (i.e. faked frames are not being | 716 // has been received from the remote side (i.e. faked frames are not being |
722 // pulled). | 717 // pulled). |
723 if (CheckRecBuffer(kHighSampleValue)) { | 718 if (CheckRecBuffer(kHighSampleValue)) { |
724 rtc::CritScope cs(&crit_); | 719 rtc::CritScope cs(&crit_); |
725 ++frames_received_; | 720 ++frames_received_; |
726 } | 721 } |
727 } | 722 } |
728 | 723 |
729 void FakeAudioCaptureModule::SendFrameP() { | 724 void FakeAudioCaptureModule::SendFrameP() { |
730 ASSERT(rtc::Thread::Current() == process_thread_); | 725 ASSERT(process_thread_->IsCurrent()); |
731 rtc::CritScope cs(&crit_callback_); | 726 rtc::CritScope cs(&crit_callback_); |
732 if (!audio_callback_) { | 727 if (!audio_callback_) { |
733 return; | 728 return; |
734 } | 729 } |
735 bool key_pressed = false; | 730 bool key_pressed = false; |
736 uint32_t current_mic_level = 0; | 731 uint32_t current_mic_level = 0; |
737 MicrophoneVolume(¤t_mic_level); | 732 MicrophoneVolume(¤t_mic_level); |
738 if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples, | 733 if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples, |
739 kNumberBytesPerSample, | 734 kNumberBytesPerSample, |
740 kNumberOfChannels, | 735 kNumberOfChannels, |
741 kSamplesPerSecond, kTotalDelayMs, | 736 kSamplesPerSecond, kTotalDelayMs, |
742 kClockDriftMs, current_mic_level, | 737 kClockDriftMs, current_mic_level, |
743 key_pressed, | 738 key_pressed, |
744 current_mic_level) != 0) { | 739 current_mic_level) != 0) { |
745 ASSERT(false); | 740 ASSERT(false); |
746 } | 741 } |
747 SetMicrophoneVolume(current_mic_level); | 742 SetMicrophoneVolume(current_mic_level); |
748 } | 743 } |
749 | 744 |
750 void FakeAudioCaptureModule::StopProcessP() { | |
751 ASSERT(rtc::Thread::Current() == process_thread_); | |
752 started_ = false; | |
753 process_thread_->Clear(this); | |
754 } | |
OLD | NEW |