OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... | |
33 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_utils. h" | 33 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_utils. h" |
34 #include "webrtc/modules/audio_processing/noise_suppression_impl.h" | 34 #include "webrtc/modules/audio_processing/noise_suppression_impl.h" |
35 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 35 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
36 #include "webrtc/test/testsupport/fileutils.h" | 36 #include "webrtc/test/testsupport/fileutils.h" |
37 | 37 |
38 using std::complex; | 38 using std::complex; |
39 | 39 |
40 namespace webrtc { | 40 namespace webrtc { |
41 namespace { | 41 namespace { |
42 | 42 |
43 DEFINE_double(clear_alpha, 0.9, "Power decay factor for clear data."); | |
44 DEFINE_int32(sample_rate, | |
45 16000, | |
46 "Audio sample rate used in the input and output files."); | |
47 DEFINE_int32(ana_rate, | |
48 60, | |
49 "Analysis rate; gains recalculated every N blocks."); | |
50 DEFINE_double(gain_limit, 1000.0, "Maximum gain change in one block."); | |
51 | |
52 DEFINE_string(clear_file, "speech.wav", "Input file with clear speech."); | 43 DEFINE_string(clear_file, "speech.wav", "Input file with clear speech."); |
53 DEFINE_string(noise_file, "noise.wav", "Input file with noise data."); | 44 DEFINE_string(noise_file, "noise.wav", "Input file with noise data."); |
54 DEFINE_string(out_file, | 45 DEFINE_string(out_file, |
55 "proc_enhanced.wav", | 46 "proc_enhanced.wav", |
56 "Enhanced output. Use '-' to " | 47 "Enhanced output. Use '-' to " |
57 "play through aplay immediately."); | 48 "play through aplay immediately."); |
58 | 49 |
59 const size_t kNumChannels = 1; | |
60 | |
61 // void function for gtest | 50 // void function for gtest |
62 void void_main(int argc, char* argv[]) { | 51 void void_main(int argc, char* argv[]) { |
63 google::SetUsageMessage( | 52 google::SetUsageMessage( |
64 "\n\nInput files must be little-endian 16-bit signed raw PCM.\n"); | 53 "\n\nInput files must be little-endian 16-bit signed raw PCM.\n"); |
65 google::ParseCommandLineFlags(&argc, &argv, true); | 54 google::ParseCommandLineFlags(&argc, &argv, true); |
66 | 55 |
67 size_t samples; // Number of samples in input PCM file | |
68 size_t fragment_size; // Number of samples to process at a time | |
69 // to simulate APM stream processing | |
70 | |
71 // Load settings and wav input. | 56 // Load settings and wav input. |
72 | |
73 fragment_size = FLAGS_sample_rate / 100; // Mirror real time APM chunk size. | |
74 // Duplicates chunk_length_ in | |
75 // IntelligibilityEnhancer. | |
76 | |
77 struct stat in_stat, noise_stat; | 57 struct stat in_stat, noise_stat; |
78 ASSERT_EQ(stat(FLAGS_clear_file.c_str(), &in_stat), 0) | 58 ASSERT_EQ(stat(FLAGS_clear_file.c_str(), &in_stat), 0) |
79 << "Empty speech file."; | 59 << "Empty speech file."; |
80 ASSERT_EQ(stat(FLAGS_noise_file.c_str(), &noise_stat), 0) | 60 ASSERT_EQ(stat(FLAGS_noise_file.c_str(), &noise_stat), 0) |
81 << "Empty noise file."; | 61 << "Empty noise file."; |
82 | 62 |
83 samples = std::min(in_stat.st_size, noise_stat.st_size) / 2; | 63 size_t samples = std::min(in_stat.st_size, noise_stat.st_size) / 2; |
hlundin-webrtc
2016/02/15 13:05:12
const?
aluebs-webrtc
2016/02/19 03:56:31
Done.
| |
84 | 64 |
85 WavReader in_file(FLAGS_clear_file); | 65 WavReader in_file(FLAGS_clear_file); |
86 std::vector<float> in_fpcm(samples); | 66 std::vector<float> in_fpcm(samples); |
87 in_file.ReadSamples(samples, &in_fpcm[0]); | 67 in_file.ReadSamples(samples, &in_fpcm[0]); |
88 FloatS16ToFloat(&in_fpcm[0], samples, &in_fpcm[0]); | 68 FloatS16ToFloat(&in_fpcm[0], samples, &in_fpcm[0]); |
89 | 69 |
90 WavReader noise_file(FLAGS_noise_file); | 70 WavReader noise_file(FLAGS_noise_file); |
91 std::vector<float> noise_fpcm(samples); | 71 std::vector<float> noise_fpcm(samples); |
92 noise_file.ReadSamples(samples, &noise_fpcm[0]); | 72 noise_file.ReadSamples(samples, &noise_fpcm[0]); |
93 FloatS16ToFloat(&noise_fpcm[0], samples, &noise_fpcm[0]); | 73 FloatS16ToFloat(&noise_fpcm[0], samples, &noise_fpcm[0]); |
94 | 74 |
95 // Run intelligibility enhancement. | 75 // Run intelligibility enhancement. |
96 IntelligibilityEnhancer::Config config; | 76 IntelligibilityEnhancer enh(in_file.sample_rate(), in_file.num_channels()); |
97 config.sample_rate_hz = FLAGS_sample_rate; | |
98 config.decay_rate = static_cast<float>(FLAGS_clear_alpha); | |
99 config.analysis_rate = FLAGS_ana_rate; | |
100 config.gain_change_limit = FLAGS_gain_limit; | |
101 IntelligibilityEnhancer enh(config); | |
102 rtc::CriticalSection crit; | 77 rtc::CriticalSection crit; |
103 NoiseSuppressionImpl ns(&crit); | 78 NoiseSuppressionImpl ns(&crit); |
104 ns.Initialize(kNumChannels, FLAGS_sample_rate); | 79 ns.Initialize(noise_file.num_channels(), noise_file.sample_rate()); |
105 ns.Enable(true); | 80 ns.Enable(true); |
106 | 81 |
82 // Mirror real time APM chunk size. Duplicates chunk_length_ in | |
83 // IntelligibilityEnhancer. | |
84 size_t fragment_size = in_file.sample_rate() / 100; | |
107 AudioBuffer capture_audio(fragment_size, | 85 AudioBuffer capture_audio(fragment_size, |
108 kNumChannels, | 86 noise_file.num_channels(), |
109 fragment_size, | 87 fragment_size, |
110 kNumChannels, | 88 noise_file.num_channels(), |
111 fragment_size); | 89 fragment_size); |
112 StreamConfig stream_config(FLAGS_sample_rate, kNumChannels); | 90 StreamConfig stream_config(in_file.sample_rate(), noise_file.num_channels()); |
113 | 91 |
114 // Slice the input into smaller chunks, as the APM would do, and feed them | 92 // Slice the input into smaller chunks, as the APM would do, and feed them |
115 // through the enhancer. | 93 // through the enhancer. |
116 float* clear_cursor = &in_fpcm[0]; | 94 float* clear_cursor = &in_fpcm[0]; |
117 float* noise_cursor = &noise_fpcm[0]; | 95 float* noise_cursor = &noise_fpcm[0]; |
118 | 96 |
119 for (size_t i = 0; i < samples; i += fragment_size) { | 97 for (size_t i = 0; i < samples; i += fragment_size) { |
120 capture_audio.CopyFrom(&noise_cursor, stream_config); | 98 capture_audio.CopyFrom(&noise_cursor, stream_config); |
121 ns.AnalyzeCaptureAudio(&capture_audio); | 99 ns.AnalyzeCaptureAudio(&capture_audio); |
122 ns.ProcessCaptureAudio(&capture_audio); | 100 ns.ProcessCaptureAudio(&capture_audio); |
123 enh.SetCaptureNoiseEstimate(ns.NoiseEstimate()); | 101 enh.SetCaptureNoiseEstimate(ns.NoiseEstimate()); |
124 enh.ProcessRenderAudio(&clear_cursor, FLAGS_sample_rate, kNumChannels); | 102 enh.ProcessRenderAudio(&clear_cursor, |
103 in_file.sample_rate(), | |
104 in_file.num_channels()); | |
125 clear_cursor += fragment_size; | 105 clear_cursor += fragment_size; |
126 noise_cursor += fragment_size; | 106 noise_cursor += fragment_size; |
127 } | 107 } |
128 | 108 |
129 FloatToFloatS16(&in_fpcm[0], samples, &in_fpcm[0]); | 109 FloatToFloatS16(&in_fpcm[0], samples, &in_fpcm[0]); |
130 | 110 |
131 if (FLAGS_out_file.compare("-") == 0) { | 111 if (FLAGS_out_file.compare("-") == 0) { |
132 const std::string temp_out_filename = | 112 const std::string temp_out_filename = |
133 test::TempFilename(test::WorkingDir(), "temp_wav_file"); | 113 test::TempFilename(test::WorkingDir(), "temp_wav_file"); |
134 { | 114 { |
135 WavWriter out_file(temp_out_filename, FLAGS_sample_rate, kNumChannels); | 115 WavWriter out_file(temp_out_filename, |
116 in_file.sample_rate(), | |
117 in_file.num_channels()); | |
136 out_file.WriteSamples(&in_fpcm[0], samples); | 118 out_file.WriteSamples(&in_fpcm[0], samples); |
137 } | 119 } |
138 system(("aplay " + temp_out_filename).c_str()); | 120 system(("aplay " + temp_out_filename).c_str()); |
139 system(("rm " + temp_out_filename).c_str()); | 121 system(("rm " + temp_out_filename).c_str()); |
140 } else { | 122 } else { |
141 WavWriter out_file(FLAGS_out_file, FLAGS_sample_rate, kNumChannels); | 123 WavWriter out_file(FLAGS_out_file, |
124 in_file.sample_rate(), | |
125 in_file.num_channels()); | |
142 out_file.WriteSamples(&in_fpcm[0], samples); | 126 out_file.WriteSamples(&in_fpcm[0], samples); |
143 } | 127 } |
144 } | 128 } |
145 | 129 |
146 } // namespace | 130 } // namespace |
147 } // namespace webrtc | 131 } // namespace webrtc |
148 | 132 |
149 int main(int argc, char* argv[]) { | 133 int main(int argc, char* argv[]) { |
150 webrtc::void_main(argc, argv); | 134 webrtc::void_main(argc, argv); |
151 return 0; | 135 return 0; |
152 } | 136 } |
OLD | NEW |