1/* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/test/testsupport/fileutils.h" 12#include "webrtc/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h" 13 14namespace { 15 16const int kSampleRateHz = 16000; 17const int kTestDurationMs = 1000; 18const int kSkipOutputMs = 50; 19const int16_t kInputValue = 15000; 20const int16_t kSilenceValue = 0; 21 22} // namespace 23 24class FileBeforeStreamingTest : public AfterInitializationFixture { 25 protected: 26 FileBeforeStreamingTest() 27 : input_filename_(webrtc::test::OutputPath() + "file_test_input.pcm"), 28 output_filename_(webrtc::test::OutputPath() + "file_test_output.pcm") { 29 } 30 31 void SetUp() { 32 channel_ = voe_base_->CreateChannel(); 33 } 34 35 void TearDown() { 36 voe_base_->DeleteChannel(channel_); 37 } 38 39 // TODO(andrew): consolidate below methods in a shared place? 40 41 // Generate input file with constant values as |kInputValue|. The file 42 // will be one second longer than the duration of the test. 43 void GenerateInputFile() { 44 FILE* input_file = fopen(input_filename_.c_str(), "wb"); 45 ASSERT_TRUE(input_file != NULL); 46 for (int i = 0; i < kSampleRateHz / 1000 * (kTestDurationMs + 1000); i++) { 47 ASSERT_EQ(1u, fwrite(&kInputValue, sizeof(kInputValue), 1, input_file)); 48 } 49 ASSERT_EQ(0, fclose(input_file)); 50 } 51 52 void RecordOutput() { 53 // Start recording the mixed output for |kTestDurationMs| long. 54 EXPECT_EQ(0, voe_file_->StartRecordingPlayout(-1, 55 output_filename_.c_str())); 56 Sleep(kTestDurationMs); 57 EXPECT_EQ(0, voe_file_->StopRecordingPlayout(-1)); 58 } 59 60 void VerifyOutput(int16_t target_value) { 61 FILE* output_file = fopen(output_filename_.c_str(), "rb"); 62 ASSERT_TRUE(output_file != NULL); 63 int16_t output_value = 0; 64 int samples_read = 0; 65 66 // Skip the first segment to avoid initialization and ramping-in effects. 67 EXPECT_EQ(0, fseek(output_file, sizeof(output_value) * 68 kSampleRateHz / 1000 * kSkipOutputMs, SEEK_SET)); 69 while (fread(&output_value, sizeof(output_value), 1, output_file) == 1) { 70 samples_read++; 71 EXPECT_EQ(output_value, target_value); 72 } 73 74 // Ensure that a reasonable amount was recorded. We use a loose 75 // tolerance to avoid flaky bot failures. 76 ASSERT_GE((samples_read * 1000.0) / kSampleRateHz, 0.4 * kTestDurationMs); 77 78 // Ensure we read the entire file. 79 ASSERT_NE(0, feof(output_file)); 80 ASSERT_EQ(0, fclose(output_file)); 81 } 82 83void VerifyEmptyOutput() { 84 FILE* output_file = fopen(output_filename_.c_str(), "rb"); 85 ASSERT_TRUE(output_file != NULL); 86 ASSERT_EQ(0, fseek(output_file, 0, SEEK_END)); 87 EXPECT_EQ(0, ftell(output_file)); 88 ASSERT_EQ(0, fclose(output_file)); 89} 90 91 int channel_; 92 const std::string input_filename_; 93 const std::string output_filename_; 94}; 95 96// This test case is to ensure that StartPlayingFileLocally() and 97// StartPlayout() can be called in any order. 98// A DC signal is used as input. And the output of mixer is supposed to be: 99// 1. the same DC signal if file is played out, 100// 2. total silence if file is not played out, 101// 3. no output if playout is not started. 102TEST_F(FileBeforeStreamingTest, TestStartPlayingFileLocallyWithStartPlayout) { 103 GenerateInputFile(); 104 105 TEST_LOG("Playout is not started. File will not be played out.\n"); 106 EXPECT_EQ(0, voe_file_->StartPlayingFileLocally( 107 channel_, input_filename_.c_str(), true)); 108 EXPECT_EQ(1, voe_file_->IsPlayingFileLocally(channel_)); 109 RecordOutput(); 110 VerifyEmptyOutput(); 111 112 TEST_LOG("Playout is now started. File will be played out.\n"); 113 EXPECT_EQ(0, voe_base_->StartPlayout(channel_)); 114 RecordOutput(); 115 VerifyOutput(kInputValue); 116 117 TEST_LOG("Stop playing file. Only silence will be played out.\n"); 118 EXPECT_EQ(0, voe_file_->StopPlayingFileLocally(channel_)); 119 EXPECT_EQ(0, voe_file_->IsPlayingFileLocally(channel_)); 120 RecordOutput(); 121 VerifyOutput(kSilenceValue); 122 123 TEST_LOG("Start playing file again. File will be played out.\n"); 124 EXPECT_EQ(0, voe_file_->StartPlayingFileLocally( 125 channel_, input_filename_.c_str(), true)); 126 EXPECT_EQ(1, voe_file_->IsPlayingFileLocally(channel_)); 127 RecordOutput(); 128 VerifyOutput(kInputValue); 129 130 EXPECT_EQ(0, voe_base_->StopPlayout(channel_)); 131 EXPECT_EQ(0, voe_file_->StopPlayingFileLocally(channel_)); 132} 133