Home | History | Annotate | Download | only in filters
      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
      3 // found in the LICENSE file.
      4 //
      5 // The format of these tests are to enqueue a known amount of data and then
      6 // request the exact amount we expect in order to dequeue the known amount of
      7 // data.  This ensures that for any rate we are consuming input data at the
      8 // correct rate.  We always pass in a very large destination buffer with the
      9 // expectation that FillBuffer() will fill as much as it can but no more.
     10 
     11 #include <cmath>
     12 
     13 #include "base/bind.h"
     14 #include "base/callback.h"
     15 #include "media/base/audio_buffer.h"
     16 #include "media/base/audio_bus.h"
     17 #include "media/base/buffers.h"
     18 #include "media/base/channel_layout.h"
     19 #include "media/base/test_helpers.h"
     20 #include "media/filters/audio_renderer_algorithm.h"
     21 #include "testing/gtest/include/gtest/gtest.h"
     22 
     23 namespace media {
     24 
     25 static const int kFrameSize = 250;
     26 static const int kSamplesPerSecond = 3000;
     27 static const SampleFormat kSampleFormat = kSampleFormatS16;
     28 
     29 class AudioRendererAlgorithmTest : public testing::Test {
     30  public:
     31   AudioRendererAlgorithmTest()
     32       : frames_enqueued_(0),
     33         channels_(0),
     34         sample_format_(kUnknownSampleFormat),
     35         bytes_per_sample_(0) {
     36   }
     37 
     38   virtual ~AudioRendererAlgorithmTest() {}
     39 
     40   void Initialize() {
     41     Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 3000);
     42   }
     43 
     44   void Initialize(ChannelLayout channel_layout,
     45                   SampleFormat sample_format,
     46                   int samples_per_second) {
     47     channels_ = ChannelLayoutToChannelCount(channel_layout);
     48     sample_format_ = sample_format;
     49     bytes_per_sample_ = SampleFormatToBytesPerChannel(sample_format);
     50     AudioParameters params(media::AudioParameters::AUDIO_PCM_LINEAR,
     51                            channel_layout,
     52                            samples_per_second,
     53                            bytes_per_sample_ * 8,
     54                            samples_per_second / 100);
     55     algorithm_.Initialize(1, params);
     56     FillAlgorithmQueue();
     57   }
     58 
     59   void FillAlgorithmQueue() {
     60     // The value of the data is meaningless; we just want non-zero data to
     61     // differentiate it from muted data.
     62     scoped_refptr<AudioBuffer> buffer;
     63     while (!algorithm_.IsQueueFull()) {
     64       switch (sample_format_) {
     65         case kSampleFormatU8:
     66           buffer = MakeInterleavedAudioBuffer<uint8>(sample_format_,
     67                                                      channels_,
     68                                                      1,
     69                                                      1,
     70                                                      kFrameSize,
     71                                                      kNoTimestamp(),
     72                                                      kNoTimestamp());
     73           break;
     74         case kSampleFormatS16:
     75           buffer = MakeInterleavedAudioBuffer<int16>(sample_format_,
     76                                                      channels_,
     77                                                      1,
     78                                                      1,
     79                                                      kFrameSize,
     80                                                      kNoTimestamp(),
     81                                                      kNoTimestamp());
     82           break;
     83         case kSampleFormatS32:
     84           buffer = MakeInterleavedAudioBuffer<int32>(sample_format_,
     85                                                      channels_,
     86                                                      1,
     87                                                      1,
     88                                                      kFrameSize,
     89                                                      kNoTimestamp(),
     90                                                      kNoTimestamp());
     91           break;
     92         default:
     93           NOTREACHED() << "Unrecognized format " << sample_format_;
     94       }
     95       algorithm_.EnqueueBuffer(buffer);
     96       frames_enqueued_ += kFrameSize;
     97     }
     98   }
     99 
    100   void CheckFakeData(AudioBus* audio_data, int frames_written) {
    101     // Check each channel individually.
    102     for (int ch = 0; ch < channels_; ++ch) {
    103       bool all_zero = true;
    104       for (int i = 0; i < frames_written && all_zero; ++i)
    105         all_zero = audio_data->channel(ch)[i] == 0.0f;
    106       ASSERT_EQ(algorithm_.is_muted(), all_zero) << " for channel " << ch;
    107     }
    108   }
    109 
    110   int ComputeConsumedFrames(int initial_frames_enqueued,
    111                             int initial_frames_buffered) {
    112     int frame_delta = frames_enqueued_ - initial_frames_enqueued;
    113     int buffered_delta = algorithm_.frames_buffered() - initial_frames_buffered;
    114     int consumed = frame_delta - buffered_delta;
    115     CHECK_GE(consumed, 0);
    116     return consumed;
    117   }
    118 
    119   void TestPlaybackRate(double playback_rate) {
    120     const int kDefaultBufferSize = algorithm_.samples_per_second() / 100;
    121     const int kDefaultFramesRequested = 2 * algorithm_.samples_per_second();
    122 
    123     TestPlaybackRate(
    124         playback_rate, kDefaultBufferSize, kDefaultFramesRequested);
    125   }
    126 
    127   void TestPlaybackRate(double playback_rate,
    128                         int buffer_size_in_frames,
    129                         int total_frames_requested) {
    130     int initial_frames_enqueued = frames_enqueued_;
    131     int initial_frames_buffered = algorithm_.frames_buffered();
    132     algorithm_.SetPlaybackRate(static_cast<float>(playback_rate));
    133 
    134     scoped_ptr<AudioBus> bus =
    135         AudioBus::Create(channels_, buffer_size_in_frames);
    136     if (playback_rate == 0.0) {
    137       int frames_written =
    138           algorithm_.FillBuffer(bus.get(), buffer_size_in_frames);
    139       EXPECT_EQ(0, frames_written);
    140       return;
    141     }
    142 
    143     int frames_remaining = total_frames_requested;
    144     while (frames_remaining > 0) {
    145       int frames_requested = std::min(buffer_size_in_frames, frames_remaining);
    146       int frames_written = algorithm_.FillBuffer(bus.get(), frames_requested);
    147       ASSERT_GT(frames_written, 0) << "Requested: " << frames_requested
    148                                    << ", playing at " << playback_rate;
    149       CheckFakeData(bus.get(), frames_written);
    150       frames_remaining -= frames_written;
    151 
    152       FillAlgorithmQueue();
    153     }
    154 
    155     int frames_consumed =
    156         ComputeConsumedFrames(initial_frames_enqueued, initial_frames_buffered);
    157 
    158     // If playing back at normal speed, we should always get back the same
    159     // number of bytes requested.
    160     if (playback_rate == 1.0) {
    161       EXPECT_EQ(total_frames_requested, frames_consumed);
    162       return;
    163     }
    164 
    165     // Otherwise, allow |kMaxAcceptableDelta| difference between the target and
    166     // actual playback rate.
    167     // When |kSamplesPerSecond| and |total_frames_requested| are reasonably
    168     // large, one can expect less than a 1% difference in most cases. In our
    169     // current implementation, sped up playback is less accurate than slowed
    170     // down playback, and for playback_rate > 1, playback rate generally gets
    171     // less and less accurate the farther it drifts from 1 (though this is
    172     // nonlinear).
    173     double actual_playback_rate =
    174         1.0 * frames_consumed / total_frames_requested;
    175     EXPECT_NEAR(playback_rate, actual_playback_rate, playback_rate / 100.0);
    176   }
    177 
    178  protected:
    179   AudioRendererAlgorithm algorithm_;
    180   int frames_enqueued_;
    181   int channels_;
    182   SampleFormat sample_format_;
    183   int bytes_per_sample_;
    184 };
    185 
    186 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NormalRate) {
    187   Initialize();
    188   TestPlaybackRate(1.0);
    189 }
    190 
    191 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalFasterRate) {
    192   Initialize();
    193   TestPlaybackRate(1.0001);
    194 }
    195 
    196 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalSlowerRate) {
    197   Initialize();
    198   TestPlaybackRate(0.9999);
    199 }
    200 
    201 TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAQuarterRate) {
    202   Initialize();
    203   TestPlaybackRate(1.25);
    204 }
    205 
    206 TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAHalfRate) {
    207   Initialize();
    208   TestPlaybackRate(1.5);
    209 }
    210 
    211 TEST_F(AudioRendererAlgorithmTest, FillBuffer_DoubleRate) {
    212   Initialize();
    213   TestPlaybackRate(2.0);
    214 }
    215 
    216 TEST_F(AudioRendererAlgorithmTest, FillBuffer_EightTimesRate) {
    217   Initialize();
    218   TestPlaybackRate(8.0);
    219 }
    220 
    221 TEST_F(AudioRendererAlgorithmTest, FillBuffer_ThreeQuartersRate) {
    222   Initialize();
    223   TestPlaybackRate(0.75);
    224 }
    225 
    226 TEST_F(AudioRendererAlgorithmTest, FillBuffer_HalfRate) {
    227   Initialize();
    228   TestPlaybackRate(0.5);
    229 }
    230 
    231 TEST_F(AudioRendererAlgorithmTest, FillBuffer_QuarterRate) {
    232   Initialize();
    233   TestPlaybackRate(0.25);
    234 }
    235 
    236 TEST_F(AudioRendererAlgorithmTest, FillBuffer_Pause) {
    237   Initialize();
    238   TestPlaybackRate(0.0);
    239 }
    240 
    241 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SlowDown) {
    242   Initialize();
    243   TestPlaybackRate(4.5);
    244   TestPlaybackRate(3.0);
    245   TestPlaybackRate(2.0);
    246   TestPlaybackRate(1.0);
    247   TestPlaybackRate(0.5);
    248   TestPlaybackRate(0.25);
    249 }
    250 
    251 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SpeedUp) {
    252   Initialize();
    253   TestPlaybackRate(0.25);
    254   TestPlaybackRate(0.5);
    255   TestPlaybackRate(1.0);
    256   TestPlaybackRate(2.0);
    257   TestPlaybackRate(3.0);
    258   TestPlaybackRate(4.5);
    259 }
    260 
    261 TEST_F(AudioRendererAlgorithmTest, FillBuffer_JumpAroundSpeeds) {
    262   Initialize();
    263   TestPlaybackRate(2.1);
    264   TestPlaybackRate(0.9);
    265   TestPlaybackRate(0.6);
    266   TestPlaybackRate(1.4);
    267   TestPlaybackRate(0.3);
    268 }
    269 
    270 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SmallBufferSize) {
    271   Initialize();
    272   static const int kBufferSizeInFrames = 1;
    273   static const int kFramesRequested = 2 * kSamplesPerSecond;
    274   TestPlaybackRate(1.0, kBufferSizeInFrames, kFramesRequested);
    275   TestPlaybackRate(0.5, kBufferSizeInFrames, kFramesRequested);
    276   TestPlaybackRate(1.5, kBufferSizeInFrames, kFramesRequested);
    277 }
    278 
    279 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LargeBufferSize) {
    280   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 44100);
    281   TestPlaybackRate(1.0);
    282   TestPlaybackRate(0.5);
    283   TestPlaybackRate(1.5);
    284 }
    285 
    286 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LowerQualityAudio) {
    287   Initialize(CHANNEL_LAYOUT_MONO, kSampleFormatU8, kSamplesPerSecond);
    288   TestPlaybackRate(1.0);
    289   TestPlaybackRate(0.5);
    290   TestPlaybackRate(1.5);
    291 }
    292 
    293 TEST_F(AudioRendererAlgorithmTest, FillBuffer_HigherQualityAudio) {
    294   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS32, kSamplesPerSecond);
    295   TestPlaybackRate(1.0);
    296   TestPlaybackRate(0.5);
    297   TestPlaybackRate(1.5);
    298 }
    299 
    300 }  // namespace media
    301