OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include <stdint.h> |
| 6 |
5 #include "content/browser/speech/audio_buffer.h" | 7 #include "content/browser/speech/audio_buffer.h" |
6 #include "content/browser/speech/endpointer/endpointer.h" | 8 #include "content/browser/speech/endpointer/endpointer.h" |
7 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
8 | 10 |
9 namespace { | 11 namespace { |
10 const int kFrameRate = 50; // 20 ms long frames for AMR encoding. | 12 const int kFrameRate = 50; // 20 ms long frames for AMR encoding. |
11 const int kSampleRate = 8000; // 8 k samples per second for AMR encoding. | 13 const int kSampleRate = 8000; // 8 k samples per second for AMR encoding. |
12 | 14 |
13 // At 8 sample per second a 20 ms frame is 160 samples, which corrsponds | 15 // At 8 sample per second a 20 ms frame is 160 samples, which corrsponds |
14 // to the AMR codec. | 16 // to the AMR codec. |
15 const int kFrameSize = kSampleRate / kFrameRate; // 160 samples. | 17 const int kFrameSize = kSampleRate / kFrameRate; // 160 samples. |
16 static_assert(kFrameSize == 160, "invalid frame size"); | 18 static_assert(kFrameSize == 160, "invalid frame size"); |
17 } | 19 } |
18 | 20 |
19 namespace content { | 21 namespace content { |
20 | 22 |
21 class FrameProcessor { | 23 class FrameProcessor { |
22 public: | 24 public: |
23 // Process a single frame of test audio samples. | 25 // Process a single frame of test audio samples. |
24 virtual EpStatus ProcessFrame(int64 time, int16* samples, int frame_size) = 0; | 26 virtual EpStatus ProcessFrame(int64_t time, |
| 27 int16_t* samples, |
| 28 int frame_size) = 0; |
25 }; | 29 }; |
26 | 30 |
27 void RunEndpointerEventsTest(FrameProcessor* processor) { | 31 void RunEndpointerEventsTest(FrameProcessor* processor) { |
28 int16 samples[kFrameSize]; | 32 int16_t samples[kFrameSize]; |
29 | 33 |
30 // We will create a white noise signal of 150 frames. The frames from 50 to | 34 // We will create a white noise signal of 150 frames. The frames from 50 to |
31 // 100 will have more power, and the endpointer should fire on those frames. | 35 // 100 will have more power, and the endpointer should fire on those frames. |
32 const int kNumFrames = 150; | 36 const int kNumFrames = 150; |
33 | 37 |
34 // Create a random sequence of samples. | 38 // Create a random sequence of samples. |
35 srand(1); | 39 srand(1); |
36 float gain = 0.0; | 40 float gain = 0.0; |
37 int64 time = 0; | 41 int64_t time = 0; |
38 for (int frame_count = 0; frame_count < kNumFrames; ++frame_count) { | 42 for (int frame_count = 0; frame_count < kNumFrames; ++frame_count) { |
39 // The frames from 50 to 100 will have more power, and the endpointer | 43 // The frames from 50 to 100 will have more power, and the endpointer |
40 // should detect those frames as speech. | 44 // should detect those frames as speech. |
41 if ((frame_count >= 50) && (frame_count < 100)) { | 45 if ((frame_count >= 50) && (frame_count < 100)) { |
42 gain = 2000.0; | 46 gain = 2000.0; |
43 } else { | 47 } else { |
44 gain = 1.0; | 48 gain = 1.0; |
45 } | 49 } |
46 // Create random samples. | 50 // Create random samples. |
47 for (int i = 0; i < kFrameSize; ++i) { | 51 for (int i = 0; i < kFrameSize; ++i) { |
48 float randNum = static_cast<float>(rand() - (RAND_MAX / 2)) / | 52 float randNum = static_cast<float>(rand() - (RAND_MAX / 2)) / |
49 static_cast<float>(RAND_MAX); | 53 static_cast<float>(RAND_MAX); |
50 samples[i] = static_cast<int16>(gain * randNum); | 54 samples[i] = static_cast<int16_t>(gain * randNum); |
51 } | 55 } |
52 | 56 |
53 EpStatus ep_status = processor->ProcessFrame(time, samples, kFrameSize); | 57 EpStatus ep_status = processor->ProcessFrame(time, samples, kFrameSize); |
54 time += static_cast<int64>(kFrameSize * (1e6 / kSampleRate)); | 58 time += static_cast<int64_t>(kFrameSize * (1e6 / kSampleRate)); |
55 | 59 |
56 // Log the status. | 60 // Log the status. |
57 if (20 == frame_count) | 61 if (20 == frame_count) |
58 EXPECT_EQ(EP_PRE_SPEECH, ep_status); | 62 EXPECT_EQ(EP_PRE_SPEECH, ep_status); |
59 if (70 == frame_count) | 63 if (70 == frame_count) |
60 EXPECT_EQ(EP_SPEECH_PRESENT, ep_status); | 64 EXPECT_EQ(EP_SPEECH_PRESENT, ep_status); |
61 if (120 == frame_count) | 65 if (120 == frame_count) |
62 EXPECT_EQ(EP_PRE_SPEECH, ep_status); | 66 EXPECT_EQ(EP_PRE_SPEECH, ep_status); |
63 } | 67 } |
64 } | 68 } |
65 | 69 |
66 // This test instantiates and initializes a stand alone endpointer module. | 70 // This test instantiates and initializes a stand alone endpointer module. |
67 // The test creates FrameData objects with random noise and send them | 71 // The test creates FrameData objects with random noise and send them |
68 // to the endointer module. The energy of the first 50 frames is low, | 72 // to the endointer module. The energy of the first 50 frames is low, |
69 // followed by 500 high energy frames, and another 50 low energy frames. | 73 // followed by 500 high energy frames, and another 50 low energy frames. |
70 // We test that the correct start and end frames were detected. | 74 // We test that the correct start and end frames were detected. |
71 class EnergyEndpointerFrameProcessor : public FrameProcessor { | 75 class EnergyEndpointerFrameProcessor : public FrameProcessor { |
72 public: | 76 public: |
73 explicit EnergyEndpointerFrameProcessor(EnergyEndpointer* endpointer) | 77 explicit EnergyEndpointerFrameProcessor(EnergyEndpointer* endpointer) |
74 : endpointer_(endpointer) {} | 78 : endpointer_(endpointer) {} |
75 | 79 |
76 EpStatus ProcessFrame(int64 time, int16* samples, int frame_size) override { | 80 EpStatus ProcessFrame(int64_t time, |
| 81 int16_t* samples, |
| 82 int frame_size) override { |
77 endpointer_->ProcessAudioFrame(time, samples, kFrameSize, NULL); | 83 endpointer_->ProcessAudioFrame(time, samples, kFrameSize, NULL); |
78 int64 ep_time; | 84 int64_t ep_time; |
79 return endpointer_->Status(&ep_time); | 85 return endpointer_->Status(&ep_time); |
80 } | 86 } |
81 | 87 |
82 private: | 88 private: |
83 EnergyEndpointer* endpointer_; | 89 EnergyEndpointer* endpointer_; |
84 }; | 90 }; |
85 | 91 |
86 TEST(EndpointerTest, TestEnergyEndpointerEvents) { | 92 TEST(EndpointerTest, TestEnergyEndpointerEvents) { |
87 // Initialize endpointer and configure it. We specify the parameters | 93 // Initialize endpointer and configure it. We specify the parameters |
88 // here for a 20ms window, and a 20ms step size, which corrsponds to | 94 // here for a 20ms window, and a 20ms step size, which corrsponds to |
(...skipping 20 matching lines...) Expand all Loading... |
109 | 115 |
110 endpointer.EndSession(); | 116 endpointer.EndSession(); |
111 }; | 117 }; |
112 | 118 |
113 // Test endpointer wrapper class. | 119 // Test endpointer wrapper class. |
114 class EndpointerFrameProcessor : public FrameProcessor { | 120 class EndpointerFrameProcessor : public FrameProcessor { |
115 public: | 121 public: |
116 explicit EndpointerFrameProcessor(Endpointer* endpointer) | 122 explicit EndpointerFrameProcessor(Endpointer* endpointer) |
117 : endpointer_(endpointer) {} | 123 : endpointer_(endpointer) {} |
118 | 124 |
119 EpStatus ProcessFrame(int64 time, int16* samples, int frame_size) override { | 125 EpStatus ProcessFrame(int64_t time, |
| 126 int16_t* samples, |
| 127 int frame_size) override { |
120 scoped_refptr<AudioChunk> frame( | 128 scoped_refptr<AudioChunk> frame( |
121 new AudioChunk(reinterpret_cast<uint8*>(samples), kFrameSize * 2, 2)); | 129 new AudioChunk(reinterpret_cast<uint8_t*>(samples), kFrameSize * 2, 2)); |
122 endpointer_->ProcessAudio(*frame.get(), NULL); | 130 endpointer_->ProcessAudio(*frame.get(), NULL); |
123 int64 ep_time; | 131 int64_t ep_time; |
124 return endpointer_->Status(&ep_time); | 132 return endpointer_->Status(&ep_time); |
125 } | 133 } |
126 | 134 |
127 private: | 135 private: |
128 Endpointer* endpointer_; | 136 Endpointer* endpointer_; |
129 }; | 137 }; |
130 | 138 |
131 TEST(EndpointerTest, TestEmbeddedEndpointerEvents) { | 139 TEST(EndpointerTest, TestEmbeddedEndpointerEvents) { |
132 const int kSampleRate = 8000; // 8 k samples per second for AMR encoding. | 140 const int kSampleRate = 8000; // 8 k samples per second for AMR encoding. |
133 | 141 |
134 Endpointer endpointer(kSampleRate); | 142 Endpointer endpointer(kSampleRate); |
135 const int64 kMillisecondsPerMicrosecond = 1000; | 143 const int64_t kMillisecondsPerMicrosecond = 1000; |
136 const int64 short_timeout = 300 * kMillisecondsPerMicrosecond; | 144 const int64_t short_timeout = 300 * kMillisecondsPerMicrosecond; |
137 endpointer.set_speech_input_possibly_complete_silence_length(short_timeout); | 145 endpointer.set_speech_input_possibly_complete_silence_length(short_timeout); |
138 const int64 long_timeout = 500 * kMillisecondsPerMicrosecond; | 146 const int64_t long_timeout = 500 * kMillisecondsPerMicrosecond; |
139 endpointer.set_speech_input_complete_silence_length(long_timeout); | 147 endpointer.set_speech_input_complete_silence_length(long_timeout); |
140 endpointer.StartSession(); | 148 endpointer.StartSession(); |
141 | 149 |
142 EndpointerFrameProcessor frame_processor(&endpointer); | 150 EndpointerFrameProcessor frame_processor(&endpointer); |
143 RunEndpointerEventsTest(&frame_processor); | 151 RunEndpointerEventsTest(&frame_processor); |
144 | 152 |
145 endpointer.EndSession(); | 153 endpointer.EndSession(); |
146 } | 154 } |
147 | 155 |
148 } // namespace content | 156 } // namespace content |
OLD | NEW |