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); } }