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