src/media/audio/audio_core/test/api/audio_renderer_pipeline_test.cc
// Verify the correct output is received before and after update of the OutputPipeline.
//
// AudioCore is launched with a default profile containing an inversion_filter effect; a renderer
// plays a packet, and the output is verified as inverted. Then, the AudioTuner service is used to
// update the OutputPipeline with a PipelineConfig containing a disabled inversion_filter effect. A
// second packet is played, and the output is verified as having no effects applied.
Verify the correct output is received before and after update of the OutputPipeline.
AudioCore is launched with a default profile containing an inversion_filter effect; a renderer
plays a packet, and the output is verified as inverted. Then, the AudioTuner service is used to
update the OutputPipeline with a PipelineConfig containing a disabled inversion_filter effect. A
second packet is played, and the output is verified as having no effects applied.
Verify the correct output is received before and after update of the OutputPipeline . AudioCore is launched with a default profile containing an inversion_filter effect ; a renderer plays a packet and the output is verified as inverted . Then the AudioTuner service is used to update the OutputPipeline with a PipelineConfig containing a disabled inversion_filter effect . A second packet is played and the output is verified as having no effects applied .
TEST_F(AudioRendererPipelineTuningTest, CorrectStreamOutputUponUpdatedPipeline) {
  auto num_packets = 1;
  auto num_frames = num_packets * kPacketFrames;
  auto first_buffer = GenerateSequentialAudio<ASF::SIGNED_16>(format_, num_frames);
  auto first_packets = renderer_->AppendPackets({&first_buffer});
  renderer_->PlaySynchronized(this, output_, 0);
  renderer_->WaitForPackets(this, first_packets);
  auto ring_buffer = output_->SnapshotRingBuffer();
  RunInversionFilter(&first_buffer);
  CompareAudioBufferOptions opts;
  opts.num_frames_per_packet = kPacketFrames;
  opts.test_label = "default config, first packet";
  CompareAudioBuffers(AudioBufferSlice(&ring_buffer, 0, num_frames),
                      AudioBufferSlice(&first_buffer), opts);
  renderer_->ClearPayload();
  auto device_id = AudioDevice::UniqueIdToString({{0xff, 0x00}});
  PipelineConfig::MixGroup root{.name = "linearize",
                                .input_streams =
                                    {
                                        RenderUsage::MEDIA,
                                        RenderUsage::SYSTEM_AGENT,
                                        RenderUsage::INTERRUPTION,
                                        RenderUsage::COMMUNICATION,
                                    },
                                .effects = {
                                    {
                                        .lib_name = "inversion_filter.so",
                                        .effect_name = "inversion_filter",
                                        .instance_name = "inverter",
                                        .effect_config = "disable",
                                    },
                                }};
  auto pipeline_config = PipelineConfig(root);
  auto volume_curve = VolumeCurve::DefaultForMinGain(VolumeCurve::kDefaultGainForMinVolume);
  auto device_profile_with_inversion_effect =
      ToAudioDeviceTuningProfile(pipeline_config, volume_curve);
  audio_tuner_->SetAudioDeviceProfile(
      device_id, std::move(device_profile_with_inversion_effect),
      AddCallback("SetAudioDeviceProfile", [](zx_status_t status) { EXPECT_EQ(status, ZX_OK); }));
  ExpectCallback();
  auto min_lead_time = renderer_->GetMinLeadTime();
  constexpr auto kSchedulingDelayInPackets = 10;
  const auto min_lead_time_in_packets =
      (min_lead_time / zx::msec(RendererShimImpl::kPacketMs)) + kSchedulingDelayInPackets;
  const int64_t restart_packet = 2 + min_lead_time_in_packets;
  const int64_t restart_pts = restart_packet * kPacketFrames;
  auto second_buffer = GenerateSequentialAudio<ASF::SIGNED_16>(format_, num_frames);
  auto second_packets = renderer_->AppendPackets({&second_buffer}, restart_pts);
  renderer_->WaitForPackets(this, second_packets);
  ring_buffer = output_->SnapshotRingBuffer();
  opts.num_frames_per_packet = kPacketFrames;
  opts.test_label = "updated config, remaining packets";
  CompareAudioBuffers(AudioBufferSlice(&ring_buffer, restart_pts, restart_pts + num_frames),
                      AudioBufferSlice(&second_buffer), opts);
}
TEST_F ( AudioRendererPipelineTuningTest , CorrectStreamOutputUponUpdatedPipeline ) { auto num_packets = 1 ; auto num_frames = num_packets * kPacketFrames ; auto first_buffer = GenerateSequentialAudio < ASF :: SIGNED_16 > ( format_ , num_frames ) ; auto first_packets = renderer_ -> AppendPackets ( { & first_buffer } ) ; renderer_ -> PlaySynchronized ( this , output_ , 0 ) ; renderer_ -> WaitForPackets ( this , first_packets ) ; auto ring_buffer = output_ -> SnapshotRingBuffer ( ) ; RunInversionFilter ( & first_buffer ) ; CompareAudioBufferOptions opts ; opts . num_frames_per_packet = kPacketFrames ; opts . test_label = " " ; CompareAudioBuffers ( AudioBufferSlice ( & ring_buffer , 0 , num_frames ) , AudioBufferSlice ( & first_buffer ) , opts ) ; renderer_ -> ClearPayload ( ) ; auto device_id = AudioDevice :: UniqueIdToString ( { { 0xff , 0x00 } } ) ; PipelineConfig :: MixGroup root { . name = " " , . input_streams = { RenderUsage :: MEDIA , RenderUsage :: SYSTEM_AGENT , RenderUsage :: INTERRUPTION , RenderUsage :: COMMUNICATION , } , . effects = { { . lib_name = " " , . effect_name = " " , . instance_name = " " , . effect_config = " " , } , } } ; auto pipeline_config = PipelineConfig ( root ) ; auto volume_curve = VolumeCurve :: DefaultForMinGain ( VolumeCurve :: kDefaultGainForMinVolume ) ; auto device_profile_with_inversion_effect = ToAudioDeviceTuningProfile ( pipeline_config , volume_curve ) ; audio_tuner_ -> SetAudioDeviceProfile ( device_id , std :: move ( device_profile_with_inversion_effect ) , AddCallback ( " " , [ ] ( zx_status_t status ) { EXPECT_EQ ( status , ZX_OK ) ; } ) ) ; ExpectCallback ( ) ; auto min_lead_time = renderer_ -> GetMinLeadTime ( ) ; constexpr auto kSchedulingDelayInPackets = 10 ; const auto min_lead_time_in_packets = ( min_lead_time / zx :: msec ( RendererShimImpl :: kPacketMs ) ) + kSchedulingDelayInPackets ; const int64_t restart_packet = 2 + min_lead_time_in_packets ; const int64_t restart_pts = restart_packet * kPacketFrames ; auto second_buffer = GenerateSequentialAudio < ASF :: SIGNED_16 > ( format_ , num_frames ) ; auto second_packets = renderer_ -> AppendPackets ( { & second_buffer } , restart_pts ) ; renderer_ -> WaitForPackets ( this , second_packets ) ; ring_buffer = output_ -> SnapshotRingBuffer ( ) ; opts . num_frames_per_packet = kPacketFrames ; opts . test_label = " " ; CompareAudioBuffers ( AudioBufferSlice ( & ring_buffer , restart_pts , restart_pts + num_frames ) , AudioBufferSlice ( & second_buffer ) , opts ) ; }
Verify the correct output is received before and after update of the OutputPipeline.
Verify the correct output is received before and after update of the OutputPipeline .
// Setup packet details. // Initiate stream with first packets and send through default OutputPipeline, which has an // inversion_filter effect enabled. // Prepare first buffer for comparison to expected ring buffer. // Clear payload to avoid overlap of values from old OutputPipeline ringout with values from new // OutputPipeline. // Setup new output pipeline details. // Update PipelineConfig through AudioTuner service. // Send second set of packets through new OutputPipeline (with inversion effect disabled); play // packets at least "min_lead_time" after the last audio frame previously written to the ring // buffer. // Add extra packets to allow for scheduling delay to reduce flakes in debug mode. See fxb/52410. // Verify the remaining packets have gone through the updated OutputPipeline and thus been // unmodified, due to the inversion_filter being disabled in the new configuration.