1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_CAST_TEST_UTILITY_AUDIO_UTILITY_H_ 6 #define MEDIA_CAST_TEST_UTILITY_AUDIO_UTILITY_H_ 7 8 #include "media/audio/simple_sources.h" 9 10 namespace base { 11 class TimeDelta; 12 } 13 14 namespace media { 15 class AudioBus; 16 } 17 18 namespace media { 19 namespace cast { 20 21 // Produces AudioBuses of varying duration where each successive output contains 22 // the continuation of a single sine wave. 23 class TestAudioBusFactory { 24 public: 25 TestAudioBusFactory(int num_channels, 26 int sample_rate, 27 float sine_wave_frequency, 28 float volume); 29 ~TestAudioBusFactory(); 30 31 // Creates a new AudioBus of the given |duration|, filled with the next batch 32 // of sine wave samples. 33 scoped_ptr<AudioBus> NextAudioBus(const base::TimeDelta& duration); 34 35 // A reasonable test tone. 36 static const int kMiddleANoteFreq = 440; 37 38 private: 39 const int num_channels_; 40 const int sample_rate_; 41 const float volume_; 42 SineWaveAudioSource source_; 43 44 DISALLOW_COPY_AND_ASSIGN(TestAudioBusFactory); 45 }; 46 47 // Assuming |samples| contains a single-frequency sine wave (and maybe some 48 // low-amplitude noise), count the number of times the sine wave crosses 49 // zero. 50 // 51 // Example use case: When expecting a 440 Hz tone, this can be checked using the 52 // following expression: 53 // 54 // abs((CountZeroCrossings(...) / seconds_per_frame / 2) - 440) <= 1 55 // 56 // ...where seconds_per_frame is the number of samples divided by the sampling 57 // rate. The divide by two accounts for the fact that a sine wave crosses zero 58 // twice per cycle (first downwards, then upwards). The absolute maximum 59 // difference of 1 accounts for the sine wave being out of perfect phase. 60 int CountZeroCrossings(const float* samples, int length); 61 62 // Encode |timestamp| into the samples pointed to by 'samples' in a way 63 // that should be decodable even after compressing/decompressing the audio. 64 // Assumes 48Khz sampling rate and needs at least 240 samples. Returns 65 // false if |length| of |samples| is too small. If more than 240 samples are 66 // available, then the timestamp will be repeated. |sample_offset| should 67 // contain how many samples has been encoded so far, so that we can make smooth 68 // transitions between encoded chunks. 69 // See audio_utility.cc for details on how the encoding is done. 70 bool EncodeTimestamp(uint16 timestamp, 71 size_t sample_offset, 72 size_t length, 73 float* samples); 74 75 // Decode a timestamp encoded with EncodeTimestamp. Returns true if a 76 // timestamp was found in |samples|. 77 bool DecodeTimestamp(const float* samples, size_t length, uint16* timestamp); 78 79 } // namespace cast 80 } // namespace media 81 82 #endif // MEDIA_CAST_TEST_UTILITY_AUDIO_UTILITY_H_ 83