1 // Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8
9 #include <array>
10 #include <fstream>
11 #include <memory>
12
13 #include "common_audio/wav_file.h"
14 #include "modules/audio_processing/vad/voice_activity_detector.h"
15 #include "rtc_base/flags.h"
16 #include "rtc_base/logging.h"
17
18 namespace webrtc {
19 namespace test {
20 namespace {
21
22 constexpr uint8_t kAudioFrameLengthMilliseconds = 10;
23 constexpr int kMaxSampleRate = 48000;
24 constexpr size_t kMaxFrameLen =
25 kAudioFrameLengthMilliseconds * kMaxSampleRate / 1000;
26
27 DEFINE_string(i, "", "Input wav file");
28 DEFINE_string(o_probs, "", "VAD probabilities output file");
29 DEFINE_string(o_rms, "", "VAD output file");
30
main(int argc,char * argv[])31 int main(int argc, char* argv[]) {
32 if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true))
33 return 1;
34
35 // Open wav input file and check properties.
36 WavReader wav_reader(FLAG_i);
37 if (wav_reader.num_channels() != 1) {
38 RTC_LOG(LS_ERROR) << "Only mono wav files supported";
39 return 1;
40 }
41 if (wav_reader.sample_rate() > kMaxSampleRate) {
42 RTC_LOG(LS_ERROR) << "Beyond maximum sample rate (" << kMaxSampleRate
43 << ")";
44 return 1;
45 }
46 const size_t audio_frame_len = rtc::CheckedDivExact(
47 kAudioFrameLengthMilliseconds * wav_reader.sample_rate(), 1000);
48 if (audio_frame_len > kMaxFrameLen) {
49 RTC_LOG(LS_ERROR) << "The frame size and/or the sample rate are too large.";
50 return 1;
51 }
52
53 // Create output file and write header.
54 std::ofstream out_probs_file(FLAG_o_probs, std::ofstream::binary);
55 std::ofstream out_rms_file(FLAG_o_rms, std::ofstream::binary);
56
57 // Run VAD and write decisions.
58 VoiceActivityDetector vad;
59 std::array<int16_t, kMaxFrameLen> samples;
60
61 while (true) {
62 // Process frame.
63 const auto read_samples =
64 wav_reader.ReadSamples(audio_frame_len, samples.data());
65 if (read_samples < audio_frame_len) {
66 break;
67 }
68 vad.ProcessChunk(samples.data(), audio_frame_len, wav_reader.sample_rate());
69 // Write output.
70 auto probs = vad.chunkwise_voice_probabilities();
71 auto rms = vad.chunkwise_rms();
72 RTC_CHECK_EQ(probs.size(), rms.size());
73 RTC_CHECK_EQ(sizeof(double), 8);
74
75 for (const auto& p : probs) {
76 out_probs_file.write(reinterpret_cast<const char*>(&p), 8);
77 }
78 for (const auto& r : rms) {
79 out_rms_file.write(reinterpret_cast<const char*>(&r), 8);
80 }
81 }
82
83 out_probs_file.close();
84 out_rms_file.close();
85 return 0;
86 }
87
88 } // namespace
89 } // namespace test
90 } // namespace webrtc
91
main(int argc,char * argv[])92 int main(int argc, char* argv[]) {
93 return webrtc::test::main(argc, argv);
94 }
95