| 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> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/environment.h" | 9 #include "base/environment.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 namespace media { | 30 namespace media { |
| 31 | 31 |
| 32 ACTION_P4(CheckCountAndPostQuitTask, count, limit, loop, closure) { | 32 ACTION_P4(CheckCountAndPostQuitTask, count, limit, loop, closure) { |
| 33 if (++*count >= limit) { | 33 if (++*count >= limit) { |
| 34 loop->task_runner()->PostTask(FROM_HERE, closure); | 34 loop->task_runner()->PostTask(FROM_HERE, closure); |
| 35 } | 35 } |
| 36 } | 36 } |
| 37 | 37 |
| 38 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { | 38 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { |
| 39 public: | 39 public: |
| 40 MOCK_METHOD4(OnData, | 40 MOCK_METHOD5(OnData, |
| 41 void(AudioInputStream* stream, | 41 void(AudioInputStream* stream, |
| 42 const AudioBus* src, | 42 const AudioBus* src, |
| 43 uint32_t hardware_delay_bytes, | 43 base::TimeDelta delay, |
| 44 base::TimeTicks delay_timestamp, |
| 44 double volume)); | 45 double volume)); |
| 45 MOCK_METHOD1(OnError, void(AudioInputStream* stream)); | 46 MOCK_METHOD1(OnError, void(AudioInputStream* stream)); |
| 46 }; | 47 }; |
| 47 | 48 |
| 48 // This audio sink implementation should be used for manual tests only since | 49 // This audio sink implementation should be used for manual tests only since |
| 49 // the recorded data is stored on a raw binary data file. | 50 // the recorded data is stored on a raw binary data file. |
| 50 // The last test (WriteToFileAudioSink) - which is disabled by default - | 51 // The last test (WriteToFileAudioSink) - which is disabled by default - |
| 51 // can use this audio sink to store the captured data on a file for offline | 52 // can use this audio sink to store the captured data on a file for offline |
| 52 // analysis. | 53 // analysis. |
| 53 class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { | 54 class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 76 fwrite(chunk, 1, chunk_size, file_); | 77 fwrite(chunk, 1, chunk_size, file_); |
| 77 buffer_.Seek(chunk_size); | 78 buffer_.Seek(chunk_size); |
| 78 bytes_written += chunk_size; | 79 bytes_written += chunk_size; |
| 79 } | 80 } |
| 80 fclose(file_); | 81 fclose(file_); |
| 81 } | 82 } |
| 82 | 83 |
| 83 // AudioInputStream::AudioInputCallback implementation. | 84 // AudioInputStream::AudioInputCallback implementation. |
| 84 void OnData(AudioInputStream* stream, | 85 void OnData(AudioInputStream* stream, |
| 85 const AudioBus* src, | 86 const AudioBus* src, |
| 86 uint32_t hardware_delay_bytes, | 87 base::TimeDelta delay, |
| 88 base::TimeTicks delay_timestamp, |
| 87 double volume) override { | 89 double volume) override { |
| 88 const int num_samples = src->frames() * src->channels(); | 90 const int num_samples = src->frames() * src->channels(); |
| 89 std::unique_ptr<int16_t> interleaved(new int16_t[num_samples]); | 91 std::unique_ptr<int16_t> interleaved(new int16_t[num_samples]); |
| 90 const int bytes_per_sample = sizeof(*interleaved); | 92 const int bytes_per_sample = sizeof(*interleaved); |
| 91 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); | 93 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); |
| 92 | 94 |
| 93 // Store data data in a temporary buffer to avoid making blocking | 95 // Store data data in a temporary buffer to avoid making blocking |
| 94 // fwrite() calls in the audio callback. The complete buffer will be | 96 // fwrite() calls in the audio callback. The complete buffer will be |
| 95 // written to file in the destructor. | 97 // written to file in the destructor. |
| 96 const int size = bytes_per_sample * num_samples; | 98 const int size = bytes_per_sample * num_samples; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 // Create an audio input stream which records in mono. | 209 // Create an audio input stream which records in mono. |
| 208 AudioInputStream* ais = CreateAudioInputStream(CHANNEL_LAYOUT_MONO); | 210 AudioInputStream* ais = CreateAudioInputStream(CHANNEL_LAYOUT_MONO); |
| 209 EXPECT_TRUE(ais->Open()); | 211 EXPECT_TRUE(ais->Open()); |
| 210 | 212 |
| 211 MockAudioInputCallback sink; | 213 MockAudioInputCallback sink; |
| 212 | 214 |
| 213 // We use 10ms packets and will run the test until ten packets are received. | 215 // We use 10ms packets and will run the test until ten packets are received. |
| 214 // All should contain valid packets of the same size and a valid delay | 216 // All should contain valid packets of the same size and a valid delay |
| 215 // estimate. | 217 // estimate. |
| 216 base::RunLoop run_loop; | 218 base::RunLoop run_loop; |
| 217 EXPECT_CALL(sink, OnData(ais, NotNull(), _, _)) | 219 EXPECT_CALL(sink, OnData(ais, NotNull(), _, _, _)) |
| 218 .Times(AtLeast(10)) | 220 .Times(AtLeast(10)) |
| 219 .WillRepeatedly(CheckCountAndPostQuitTask( | 221 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_, |
| 220 &count, 10, &message_loop_, run_loop.QuitClosure())); | 222 run_loop.QuitClosure())); |
| 221 ais->Start(&sink); | 223 ais->Start(&sink); |
| 222 run_loop.Run(); | 224 run_loop.Run(); |
| 223 ais->Stop(); | 225 ais->Stop(); |
| 224 ais->Close(); | 226 ais->Close(); |
| 225 | 227 |
| 226 EXPECT_FALSE(log_message_.empty()); | 228 EXPECT_FALSE(log_message_.empty()); |
| 227 } | 229 } |
| 228 | 230 |
| 229 // Verify that recording starts and stops correctly in mono using mocked sink. | 231 // Verify that recording starts and stops correctly in mono using mocked sink. |
| 230 TEST_F(MacAudioInputTest, AUAudioInputStreamVerifyStereoRecording) { | 232 TEST_F(MacAudioInputTest, AUAudioInputStreamVerifyStereoRecording) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 242 // All should contain valid packets of the same size and a valid delay | 244 // All should contain valid packets of the same size and a valid delay |
| 243 // estimate. | 245 // estimate. |
| 244 // TODO(henrika): http://crbug.com/154352 forced us to run the capture side | 246 // TODO(henrika): http://crbug.com/154352 forced us to run the capture side |
| 245 // using a native buffer size of 128 audio frames and combine it with a FIFO | 247 // using a native buffer size of 128 audio frames and combine it with a FIFO |
| 246 // to match the requested size by the client. This change might also have | 248 // to match the requested size by the client. This change might also have |
| 247 // modified the delay estimates since the existing Ge(bytes_per_packet) for | 249 // modified the delay estimates since the existing Ge(bytes_per_packet) for |
| 248 // parameter #4 does no longer pass. I am removing this restriction here to | 250 // parameter #4 does no longer pass. I am removing this restriction here to |
| 249 // ensure that we can land the patch but will revisit this test again when | 251 // ensure that we can land the patch but will revisit this test again when |
| 250 // more analysis of the delay estimates are done. | 252 // more analysis of the delay estimates are done. |
| 251 base::RunLoop run_loop; | 253 base::RunLoop run_loop; |
| 252 EXPECT_CALL(sink, OnData(ais, NotNull(), _, _)) | 254 EXPECT_CALL(sink, OnData(ais, NotNull(), _, _, _)) |
| 253 .Times(AtLeast(10)) | 255 .Times(AtLeast(10)) |
| 254 .WillRepeatedly(CheckCountAndPostQuitTask( | 256 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_, |
| 255 &count, 10, &message_loop_, run_loop.QuitClosure())); | 257 run_loop.QuitClosure())); |
| 256 ais->Start(&sink); | 258 ais->Start(&sink); |
| 257 run_loop.Run(); | 259 run_loop.Run(); |
| 258 ais->Stop(); | 260 ais->Stop(); |
| 259 ais->Close(); | 261 ais->Close(); |
| 260 | 262 |
| 261 EXPECT_FALSE(log_message_.empty()); | 263 EXPECT_FALSE(log_message_.empty()); |
| 262 } | 264 } |
| 263 | 265 |
| 264 // This test is intended for manual tests and should only be enabled | 266 // This test is intended for manual tests and should only be enabled |
| 265 // when it is required to store the captured data on a local file. | 267 // when it is required to store the captured data on a local file. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 280 WriteToFileAudioSink file_sink(file_name); | 282 WriteToFileAudioSink file_sink(file_name); |
| 281 fprintf(stderr, " >> Speak into the mic while recording...\n"); | 283 fprintf(stderr, " >> Speak into the mic while recording...\n"); |
| 282 ais->Start(&file_sink); | 284 ais->Start(&file_sink); |
| 283 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); | 285 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); |
| 284 ais->Stop(); | 286 ais->Stop(); |
| 285 fprintf(stderr, " >> Recording has stopped.\n"); | 287 fprintf(stderr, " >> Recording has stopped.\n"); |
| 286 ais->Close(); | 288 ais->Close(); |
| 287 } | 289 } |
| 288 | 290 |
| 289 } // namespace media | 291 } // namespace media |
| OLD | NEW |