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