int FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) { // Load the file if we haven't already. This load needs to happen on the // audio thread, otherwise we'll run on the UI thread on Mac for instance. // This will massively delay the first OnMoreData, but we'll catch up. if (!wav_audio_handler_) LoadWavFile(path_to_wav_file_); if (load_failed_) return 0; DCHECK(wav_audio_handler_.get()); // Stop playing if we've played out the whole file. if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) return 0; // This pulls data from ProvideInput. file_audio_converter_->Convert(audio_bus); return audio_bus->frames(); }
chrome --use-fake-device-for-media-stream \ --use-file-for-fake-audio-capture=/tmp/file.wav
// ... size_t bytes_written; wav_audio_handler->CopyTo(audio_bus.get(), 0, &bytes_written); CHECK_EQ(bytes_written, wav_audio_handler->data().size()) << "Expected to write entire file into bus."; // Set the filter coefficient to the whole file's duration; this will make // the power monitor take the entire file into account. media::AudioPowerMonitor power_monitor(wav_audio_handler->sample_rate(), file_duration); power_monitor.Scan(*audio_bus, audio_bus->frames()); // ... return power_monitor.ReadCurrentPowerAndClip().first;
base::FilePath reference_file = test::GetReferenceFilesDir().Append(reference_filename); base::FilePath recording = CreateTemporaryWaveFile(); ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall( reference_file, recording, constraints, base::TimeDelta::FromSeconds(30))); base::ScopedTempDir split_ref_files; ASSERT_TRUE(split_ref_files.CreateUniqueTempDir()); ASSERT_NO_FATAL_FAILURE( SplitFileOnSilenceIntoDir(reference_file, split_ref_files.path())); std::vector<base::FilePath> ref_segments = ListWavFilesInDir(split_ref_files.path()); base::ScopedTempDir split_actual_files; ASSERT_TRUE(split_actual_files.CreateUniqueTempDir()); ASSERT_NO_FATAL_FAILURE( SplitFileOnSilenceIntoDir(recording, split_actual_files.path())); // Keep the recording and split files if the analysis fails. base::FilePath actual_files_dir = split_actual_files.Take(); std::vector<base::FilePath> actual_segments = ListWavFilesInDir(actual_files_dir); AnalyzeSegmentsAndPrintResult( ref_segments, actual_segments, reference_file, perf_modifier); DeleteFileUnlessTestFailed(recording, false); DeleteFileUnlessTestFailed(actual_files_dir, true);
void AnalyzeSegmentsAndPrintResult( const std::vector<base::FilePath>& ref_segments, const std::vector<base::FilePath>& actual_segments, const base::FilePath& reference_file, const std::string& perf_modifier) { ASSERT_GT(ref_segments.size(), 0u) << "Failed to split reference file on silence; sox is likely broken."; ASSERT_EQ(ref_segments.size(), actual_segments.size()) << "The recording did not result in the same number of audio segments " << "after on splitting on silence; WebRTC must have deformed the audio " << "too much."; for (size_t i = 0; i < ref_segments.size(); i++) { float difference_in_decibel = AnalyzeOneSegment(ref_segments[i], actual_segments[i], i); std::string trace_name = MakeTraceName(reference_file, i); perf_test::PrintResult("agc_energy_diff", perf_modifier, trace_name, difference_in_decibel, "dB", false); } }
{ # ... 'src/third_party/webrtc': 'https://chromium.googlesource.com/' + 'external/webrtc/trunk/webrtc.git' + '@' + '5727038f572c517204e1642b8bc69b25381c4e9f', }
class WebRtcAmplifier { ... int SetOutputVolume(float volume); }
class WebRtcAmplifier { ... int SetOutputVolume(float volume, bool allow_eleven1); }
class WebRtcAmplifier { ... int SetOutputVolume(float volume); int SetOutputVolume2(float volume, bool allow_eleven); }
// Production code: def abs(i: Int) return (i < 0) ? i * -1 : i // Test code: for (line: String in File(prod_source).read_lines()) switch (line.number) 1: assert line.content equals "def abs(i: Int)" 2: assert line.content equals " return (i < 0) ? i * -1 : i"
// Production code: def process(w: Work) firstPart.process(w) secondPart.process(w) // Test code: part1 = mock(FirstPart) part2 = mock(SecondPart) w = Work() Processor(part1, part2).process(w) verify_in_order was_called part1.process(w) was_called part2.process(w)
class UserInfoValidator { public void validate(UserInfo info) { if (info.getDateOfBirth().isInFuture()) { throw new ValidationException()); } } }
public class UserInfoService { private UserInfoValidator validator; public void save(UserInfo info) { validator.validate(info); // Throw an exception if the value is invalid. writeToDatabase(info); } }