src/media/audio/audio_core/output_pipeline_unittest.cc
// This test makes assumptions about the mixer's lead-time, so we explicitly specify the
// SampleAndHold resampler. Because we compare actual duration to expected duration down to the
// nanosec, the amount of delay in our test effects is carefully chosen and may be brittle.
This test makes assumptions about the mixer's lead-time, so we explicitly specify the
SampleAndHold resampler. Because we compare actual duration to expected duration down to the
nanosec, the amount of delay in our test effects is carefully chosen and may be brittle.
This test makes assumptions about the mixer ' s lead - time so we explicitly specify the SampleAndHold resampler . Because we compare actual duration to expected duration down to the nanosec the amount of delay in our test effects is carefully chosen and may be brittle .
TEST_F(OutputPipelineTest, ReportMinLeadTime) {
  constexpr int64_t kMixLeadTimeFrames = 1;
  constexpr int64_t kEffects1LeadTimeFrames = 300;
  constexpr int64_t kEffects2LeadTimeFrames = 900;
  auto test_effects = testing::TestEffectsModule::Open();
  test_effects.AddEffect("effect_with_delay_300").WithSignalLatencyFrames(kEffects1LeadTimeFrames);
  test_effects.AddEffect("effect_with_delay_900").WithSignalLatencyFrames(kEffects2LeadTimeFrames);
  PipelineConfig::MixGroup root{
      .name = "linearize",
      .input_streams =
          {
              RenderUsage::BACKGROUND,
          },
      .effects = {},
      .inputs = {{
                     .name = "default",
                     .input_streams =
                         {
                             RenderUsage::MEDIA,
                             RenderUsage::SYSTEM_AGENT,
                             RenderUsage::INTERRUPTION,
                         },
                     .effects =
                         {
                             {
                                 .lib_name = "test_effects.so",
                                 .effect_name = "effect_with_delay_300",
                                 .effect_config = "",
                             },
                         },
                     .output_rate = kDefaultFormat.frames_per_second(),
                     .output_channels = 2,
                 },
                 {
                     .name = "communications",
                     .input_streams =
                         {
                             RenderUsage::COMMUNICATION,
                         },
                     .effects =
                         {
                             {
                                 .lib_name = "test_effects.so",
                                 .effect_name = "effect_with_delay_900",
                                 .effect_config = "",
                             },
                         },
                     .output_rate = kDefaultFormat.frames_per_second(),
                     .output_channels = 2,
                 }},
      .output_rate = kDefaultFormat.frames_per_second(),
      .output_channels = 2,
  };
  auto pipeline_config = PipelineConfig(root);
  auto volume_curve = VolumeCurve::DefaultForMinGain(VolumeCurve::kDefaultGainForMinVolume);
  auto pipeline =
      std::make_shared<OutputPipelineImpl>(pipeline_config, volume_curve, 128, kDefaultTransform,
                                           device_clock_, Mixer::Resampler::SampleAndHold);
  auto default_stream = std::make_shared<testing::FakeStream>(kDefaultFormat);
  pipeline->AddInput(default_stream, StreamUsage::WithRenderUsage(RenderUsage::MEDIA));
  auto communications_stream = std::make_shared<testing::FakeStream>(kDefaultFormat);
  pipeline->AddInput(communications_stream,
                     StreamUsage::WithRenderUsage(RenderUsage::COMMUNICATION));
  EXPECT_EQ(zx::duration(0), pipeline->GetMinLeadTime());
  const auto default_lead_time = zx::duration(kDefaultFormat.frames_per_ns().Inverse().Scale(
      kMixLeadTimeFrames + kEffects1LeadTimeFrames + kMixLeadTimeFrames));
  EXPECT_EQ(default_lead_time, default_stream->GetMinLeadTime());
  const auto communications_lead_time = zx::duration(
      zx::sec(kMixLeadTimeFrames + kEffects2LeadTimeFrames + kMixLeadTimeFrames).to_nsecs() /
      kDefaultFormat.frames_per_second());
  EXPECT_EQ(communications_lead_time, communications_stream->GetMinLeadTime());
}
TEST_F ( OutputPipelineTest , ReportMinLeadTime ) { constexpr int64_t kMixLeadTimeFrames = 1 ; constexpr int64_t kEffects1LeadTimeFrames = 300 ; constexpr int64_t kEffects2LeadTimeFrames = 900 ; auto test_effects = testing :: TestEffectsModule :: Open ( ) ; test_effects . AddEffect ( " " ) . WithSignalLatencyFrames ( kEffects1LeadTimeFrames ) ; test_effects . AddEffect ( " " ) . WithSignalLatencyFrames ( kEffects2LeadTimeFrames ) ; PipelineConfig :: MixGroup root { . name = " " , . input_streams = { RenderUsage :: BACKGROUND , } , . effects = { } , . inputs = { { . name = " " , . input_streams = { RenderUsage :: MEDIA , RenderUsage :: SYSTEM_AGENT , RenderUsage :: INTERRUPTION , } , . effects = { { . lib_name = " " , . effect_name = " " , . effect_config = " " , } , } , . output_rate = kDefaultFormat . frames_per_second ( ) , . output_channels = 2 , } , { . name = " " , . input_streams = { RenderUsage :: COMMUNICATION , } , . effects = { { . lib_name = " " , . effect_name = " " , . effect_config = " " , } , } , . output_rate = kDefaultFormat . frames_per_second ( ) , . output_channels = 2 , } } , . output_rate = kDefaultFormat . frames_per_second ( ) , . output_channels = 2 , } ; auto pipeline_config = PipelineConfig ( root ) ; auto volume_curve = VolumeCurve :: DefaultForMinGain ( VolumeCurve :: kDefaultGainForMinVolume ) ; auto pipeline = std :: make_shared < OutputPipelineImpl > ( pipeline_config , volume_curve , 128 , kDefaultTransform , device_clock_ , Mixer :: Resampler :: SampleAndHold ) ; auto default_stream = std :: make_shared < testing :: FakeStream > ( kDefaultFormat ) ; pipeline -> AddInput ( default_stream , StreamUsage :: WithRenderUsage ( RenderUsage :: MEDIA ) ) ; auto communications_stream = std :: make_shared < testing :: FakeStream > ( kDefaultFormat ) ; pipeline -> AddInput ( communications_stream , StreamUsage :: WithRenderUsage ( RenderUsage :: COMMUNICATION ) ) ; EXPECT_EQ ( zx :: duration ( 0 ) , pipeline -> GetMinLeadTime ( ) ) ; const auto default_lead_time = zx :: duration ( kDefaultFormat . frames_per_ns ( ) . Inverse ( ) . Scale ( kMixLeadTimeFrames + kEffects1LeadTimeFrames + kMixLeadTimeFrames ) ) ; EXPECT_EQ ( default_lead_time , default_stream -> GetMinLeadTime ( ) ) ; const auto communications_lead_time = zx :: duration ( zx :: sec ( kMixLeadTimeFrames + kEffects2LeadTimeFrames + kMixLeadTimeFrames ) . to_nsecs ( ) / kDefaultFormat . frames_per_second ( ) ) ; EXPECT_EQ ( communications_lead_time , communications_stream -> GetMinLeadTime ( ) ) ; }
This test makes assumptions about the mixer's lead-time, so we explicitly specify the
SampleAndHold resampler.
This test makes assumptions about the mixer ' s lead - time so we explicitly specify the SampleAndHold resampler .
// Add 2 streams, one with a MEDIA usage and one with COMMUNICATION usage. These should receive // different lead times since they have different effects (with different latencies) applied. // The pipeline itself (the root, after any MixStages or EffectsStages) requires no lead time. // MEDIA streams require 302 frames of lead time. They run through an effect that introduces 300 // frames of delay; also SampleAndHold resamplers in the 'default' and 'linearize' MixStages each // add 1 frame of lead time. // COMMUNICATION streams require 902 frames of lead time. They run through an effect that // introduces 900 frames of delay; also SampleAndHold resamplers in the 'default' and 'linearize' // MixStages each add 1 frame of lead time.