diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraph.java b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraph.java index a1882fb064..9023434d43 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraph.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraph.java @@ -18,7 +18,6 @@ package androidx.media3.transformer; import static androidx.media3.common.audio.AudioProcessor.EMPTY_BUFFER; import static androidx.media3.common.util.Assertions.checkArgument; -import static androidx.media3.common.util.Assertions.checkState; import androidx.media3.common.C; import androidx.media3.common.Format; @@ -40,21 +39,27 @@ import java.util.Objects; private final List inputInfos; private final AudioMixer mixer; + private final AudioProcessingPipeline audioProcessingPipeline; private AudioFormat mixerAudioFormat; private long pendingStartTimeUs; private int mixerSourcesToAdd; private ByteBuffer mixerOutput; - private AudioProcessingPipeline audioProcessingPipeline; private int finishedInputs; - /** Creates an instance. */ - public AudioGraph(AudioMixer.Factory mixerFactory) { + /** + * Creates an instance. + * + * @param mixerFactory The {@linkplain AudioMixer.Factory factory} used to {@linkplain + * AudioMixer.Factory#create() create} the underlying {@link AudioMixer}. + * @param effects The composition-level audio effects that are applied after mixing. + */ + public AudioGraph(AudioMixer.Factory mixerFactory, ImmutableList effects) { inputInfos = new ArrayList<>(); mixer = mixerFactory.create(); mixerAudioFormat = AudioFormat.NOT_SET; mixerOutput = EMPTY_BUFFER; - audioProcessingPipeline = new AudioProcessingPipeline(ImmutableList.of()); + audioProcessingPipeline = new AudioProcessingPipeline(effects); } /** Returns whether an {@link AudioFormat} is valid as an input format. */ @@ -73,23 +78,6 @@ import java.util.Objects; return true; } - /** - * Configures the composition-level audio effects to be applied after mixing. - * - *

Must be called before {@linkplain #registerInput(EditedMediaItem, Format) registering - * inputs}. - * - * @param effects The composition-level audio effects. - * @throws IllegalStateException If {@link #registerInput(EditedMediaItem, Format)} was already - * called. - */ - public void configure(ImmutableList effects) { - checkState( - mixerAudioFormat.equals(AudioFormat.NOT_SET), - "AudioGraph can't configure effects after input registration."); - audioProcessingPipeline = new AudioProcessingPipeline(effects); - } - /** * Returns a new {@link AudioGraphInput} instance. * diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSampleExporter.java b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSampleExporter.java index 16734db52e..6d434bd74c 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSampleExporter.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioSampleExporter.java @@ -59,8 +59,7 @@ import org.checkerframework.dataflow.qual.Pure; FallbackListener fallbackListener) throws ExportException { super(firstAssetLoaderTrackFormat, muxerWrapper); - audioGraph = new AudioGraph(mixerFactory); - audioGraph.configure(compositionAudioProcessors); + audioGraph = new AudioGraph(mixerFactory, compositionAudioProcessors); this.firstInputFormat = firstInputFormat; firstInput = audioGraph.registerInput(firstEditedMediaItem, firstInputFormat); encoderInputAudioFormat = audioGraph.getOutputAudioFormat(); diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/AudioGraphTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/AudioGraphTest.java index b24a4a870d..6ce9fb6c2e 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/AudioGraphTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/AudioGraphTest.java @@ -18,7 +18,6 @@ package androidx.media3.transformer; import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Util.getPcmFormat; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertThrows; import androidx.media3.common.C; import androidx.media3.common.MediaItem; @@ -59,7 +58,8 @@ public class AudioGraphTest { @Test public void silentItem_outputsCorrectAmountOfBytes() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); GraphInput input = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(SURROUND_50000)); input.onMediaItemChanged( @@ -75,8 +75,9 @@ public class AudioGraphTest { public void silentItem_withSampleRateChange_outputsCorrectAmountOfBytes() throws Exception { SonicAudioProcessor changeTo100000Hz = new SonicAudioProcessor(); changeTo100000Hz.setOutputSampleRateHz(100_000); - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of(changeTo100000Hz)); + AudioGraph audioGraph = + new AudioGraph( + new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(changeTo100000Hz)); GraphInput input = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(SURROUND_50000)); input.onMediaItemChanged( @@ -90,14 +91,16 @@ public class AudioGraphTest { @Test public void getOutputAudioFormat_afterInitialization_isNotSet() { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); assertThat(audioGraph.getOutputAudioFormat()).isEqualTo(AudioFormat.NOT_SET); } @Test public void getOutputAudioFormat_afterRegisterInput_matchesInputFormat() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(MONO_48000)); @@ -106,7 +109,8 @@ public class AudioGraphTest { @Test public void getOutputAudioFormat_afterFlush_isSet() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(MONO_48000)); audioGraph.flush(); @@ -116,7 +120,8 @@ public class AudioGraphTest { @Test public void registerInput_afterRegisterInput_doesNotChangeOutputFormat() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_48000)); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(MONO_44100)); @@ -126,7 +131,8 @@ public class AudioGraphTest { @Test public void registerInput_afterReset_changesOutputFormat() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_48000)); audioGraph.reset(); @@ -139,8 +145,9 @@ public class AudioGraphTest { public void registerInput_withAudioProcessor_affectsOutputFormat() throws Exception { SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); sonicAudioProcessor.setOutputSampleRateHz(48_000); - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of(sonicAudioProcessor)); + AudioGraph audioGraph = + new AudioGraph( + new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(sonicAudioProcessor)); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(SURROUND_50000)); @@ -153,8 +160,10 @@ public class AudioGraphTest { changeTo96000Hz.setOutputSampleRateHz(96_000); SonicAudioProcessor changeTo48000Hz = new SonicAudioProcessor(); changeTo48000Hz.setOutputSampleRateHz(48_000); - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of(changeTo96000Hz, changeTo48000Hz)); + AudioGraph audioGraph = + new AudioGraph( + new DefaultAudioMixer.Factory(), + /* effects= */ ImmutableList.of(changeTo96000Hz, changeTo48000Hz)); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(SURROUND_50000)); @@ -162,34 +171,22 @@ public class AudioGraphTest { } @Test - public void configure_changesOutputFormat() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); + public void createAudioGraphWithEffect_changesOutputFormat() throws Exception { SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); sonicAudioProcessor.setOutputSampleRateHz(48_000); - audioGraph.configure(ImmutableList.of(sonicAudioProcessor)); + AudioGraph audioGraph = + new AudioGraph( + new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(sonicAudioProcessor)); audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); assertThat(audioGraph.getOutputAudioFormat().sampleRate).isEqualTo(48_000); } - @Test - public void configure_afterRegisterInput_throws() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); - sonicAudioProcessor.setOutputSampleRateHz(48_000); - - audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); - - assertThrows( - IllegalStateException.class, - () -> audioGraph.configure(ImmutableList.of(sonicAudioProcessor))); - } - @Test public void blockInput_blocksInputData() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged( @@ -210,8 +207,8 @@ public class AudioGraphTest { @Test public void unblockInput_unblocksInputData() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged( @@ -233,8 +230,8 @@ public class AudioGraphTest { @Test public void setPendingStartTimeUs_discardsPrecedingData() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged( @@ -263,8 +260,8 @@ public class AudioGraphTest { @Test public void setPendingStartTimeUs_doesNotDiscardFollowingData() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged( @@ -294,8 +291,8 @@ public class AudioGraphTest { @Test public void flush_withoutAudioProcessor_clearsPendingData() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged( @@ -321,10 +318,11 @@ public class AudioGraphTest { @Test public void flush_withAudioProcessor_clearsPendingData() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); sonicAudioProcessor.setOutputSampleRateHz(48_000); - audioGraph.configure(ImmutableList.of(sonicAudioProcessor)); + AudioGraph audioGraph = + new AudioGraph( + new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(sonicAudioProcessor)); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged( @@ -350,8 +348,8 @@ public class AudioGraphTest { @Test public void isEnded_afterFlushAndWithoutAudioProcessor_isFalse() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); - audioGraph.configure(ImmutableList.of()); + AudioGraph audioGraph = + new AudioGraph(new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of()); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged( @@ -372,10 +370,11 @@ public class AudioGraphTest { @Test public void isEnded_afterFlushAndWithAudioProcessor_isFalse() throws Exception { - AudioGraph audioGraph = new AudioGraph(new DefaultAudioMixer.Factory()); SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); sonicAudioProcessor.setOutputSampleRateHz(48_000); - audioGraph.configure(ImmutableList.of(sonicAudioProcessor)); + AudioGraph audioGraph = + new AudioGraph( + new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(sonicAudioProcessor)); AudioGraphInput audioGraphInput = audioGraph.registerInput(FAKE_ITEM, getPcmFormat(STEREO_44100)); audioGraphInput.onMediaItemChanged(