1a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi/* 2a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Copyright (C) 2014 The Android Open Source Project 3a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * 4a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * you may not use this file except in compliance with the License. 6a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * You may obtain a copy of the License at 7a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * 8a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * 10a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * See the License for the specific language governing permissions and 14a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * limitations under the License. 15a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 16a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 17a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivipackage android.media.audiopolicy; 18a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 19a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.annotation.IntDef; 20e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Triviimport android.annotation.NonNull; 211b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Triviimport android.annotation.SystemApi; 22e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Triviimport android.media.AudioDeviceInfo; 23a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.AudioFormat; 24a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.AudioSystem; 25a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 26a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport java.lang.annotation.Retention; 27a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport java.lang.annotation.RetentionPolicy; 281b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Triviimport java.util.Objects; 29a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 30a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi/** 318fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi * @hide 32a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 331b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi@SystemApi 34a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivipublic class AudioMix { 35a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 36a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi private AudioMixingRule mRule; 37a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi private AudioFormat mFormat; 38a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi private int mRouteFlags; 391b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi private int mMixType = MIX_TYPE_INVALID; 40e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi 41e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi // written by AudioPolicy 425a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi int mMixState = MIX_STATE_DISABLED; 435a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi int mCallbackFlags; 444ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi String mDeviceAddress; 45a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 46e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi // initialized in constructor, read by AudioPolicyConfig 474ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi final int mDeviceSystemType; // an AudioSystem.DEVICE_* value, not AudioDeviceInfo.TYPE_* 48e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi 49a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 50a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * All parameters are guaranteed valid through the Builder. 51a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 52e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags, int callbackFlags, 534ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi int deviceType, String deviceAddress) { 54a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mRule = rule; 55a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mFormat = format; 56a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mRouteFlags = routeFlags; 571b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi mMixType = rule.getTargetMixType(); 585a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi mCallbackFlags = callbackFlags; 594ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi mDeviceSystemType = deviceType; 604ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi mDeviceAddress = (deviceAddress == null) ? new String("") : deviceAddress; 61a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 62a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 635a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi // CALLBACK_FLAG_* values: keep in sync with AudioMix::kCbFlag* values defined 645a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi // in frameworks/av/include/media/AudioPolicy.h 655a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi /** @hide */ 665a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi public final static int CALLBACK_FLAG_NOTIFY_ACTIVITY = 0x1; 675a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi // when adding new MIX_FLAG_* flags, add them to this mask of authorized masks: 685a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi private final static int CALLBACK_FLAGS_ALL = CALLBACK_FLAG_NOTIFY_ACTIVITY; 695a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi 705a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi // ROUTE_FLAG_* values: keep in sync with MIX_ROUTE_FLAG_* values defined 715a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi // in frameworks/av/include/media/AudioPolicy.h 72a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 73a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * An audio mix behavior where the output of the mix is sent to the original destination of 74a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * the audio signal, i.e. an output device for an output mix, or a recording for an input mix. 75a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 761b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @SystemApi 77a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public static final int ROUTE_FLAG_RENDER = 0x1; 78a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 79a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * An audio mix behavior where the output of the mix is rerouted back to the framework and 801b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi * is accessible for injection or capture through the {@link AudioTrack} and {@link AudioRecord} 81a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * APIs. 82a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 831b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @SystemApi 84a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public static final int ROUTE_FLAG_LOOP_BACK = 0x1 << 1; 85a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 86e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi private static final int ROUTE_FLAG_SUPPORTED = ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK; 87e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi 88cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi // MIX_TYPE_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h 891b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi /** 901b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi * @hide 911b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi * Invalid mix type, default value. 921b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi */ 931b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi public static final int MIX_TYPE_INVALID = -1; 941b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi /** 951b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi * @hide 961b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi * Mix type indicating playback streams are mixed. 971b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi */ 981b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi public static final int MIX_TYPE_PLAYERS = 0; 991b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi /** 1001b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi * @hide 1011b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi * Mix type indicating recording streams are mixed. 1021b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi */ 1031b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi public static final int MIX_TYPE_RECORDERS = 1; 1041b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi 105cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi 106cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi // MIX_STATE_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h 107cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi /** 108cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * @hide 109cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * State of a mix before its policy is enabled. 110cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi */ 111cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi @SystemApi 112cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi public static final int MIX_STATE_DISABLED = -1; 113cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi /** 114cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * @hide 115cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * State of a mix when there is no audio to mix. 116cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi */ 117cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi @SystemApi 118cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi public static final int MIX_STATE_IDLE = 0; 119cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi /** 120cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * @hide 121cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * State of a mix that is actively mixing audio. 122cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi */ 123cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi @SystemApi 124cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi public static final int MIX_STATE_MIXING = 1; 125cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi 126cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi /** 127cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * @hide 128cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * The current mixing state. 129cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * @return one of {@link #MIX_STATE_DISABLED}, {@link #MIX_STATE_IDLE}, 130cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi * {@link #MIX_STATE_MIXING}. 131cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi */ 132cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi @SystemApi 133cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi public int getMixState() { 134cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi return mMixState; 135cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi } 136cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi 137cc98c67ef7f1548766e0b742eb041579e74ba225Jean-Michel Trivi 138a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi int getRouteFlags() { 139a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi return mRouteFlags; 140a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 141a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 142a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi AudioFormat getFormat() { 143a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi return mFormat; 144a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 145a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 146a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi AudioMixingRule getRule() { 147a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi return mRule; 148a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 149a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 1501b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi /** @hide */ 1511b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi public int getMixType() { 1521b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi return mMixType; 1531b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi } 1541b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi 1558fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi void setRegistration(String regId) { 1564ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi mDeviceAddress = regId; 1578fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi } 1588fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi 1598fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi /** @hide */ 1608fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi public String getRegistration() { 1614ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi return mDeviceAddress; 1628fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi } 1638fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi 164a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** @hide */ 1657db2d8f1cc19238f3bf627b081462e3e062686dfJean-Michel Trivi public boolean isAffectingUsage(int usage) { 1667db2d8f1cc19238f3bf627b081462e3e062686dfJean-Michel Trivi return mRule.isAffectingUsage(usage); 1677db2d8f1cc19238f3bf627b081462e3e062686dfJean-Michel Trivi } 1687db2d8f1cc19238f3bf627b081462e3e062686dfJean-Michel Trivi 1697db2d8f1cc19238f3bf627b081462e3e062686dfJean-Michel Trivi /** @hide */ 1701b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @Override 171af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi public boolean equals(Object o) { 172af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi if (this == o) return true; 173af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi if (o == null || getClass() != o.getClass()) return false; 174af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi 175af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi final AudioMix that = (AudioMix) o; 176af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi return (this.mRouteFlags == that.mRouteFlags) 177af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi && (this.mRule == that.mRule) 178af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi && (this.mMixType == that.mMixType) 179af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi && (this.mFormat == that.mFormat); 180af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi } 181af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi 182af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi /** @hide */ 183af576a0e4fa9c9fe06a185007d5f201d80e4ebd1Jean-Michel Trivi @Override 1841b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi public int hashCode() { 1851b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi return Objects.hash(mRouteFlags, mRule, mMixType, mFormat); 1861b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi } 1871b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi 1881b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi /** @hide */ 189a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi @IntDef(flag = true, 190a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi value = { ROUTE_FLAG_RENDER, ROUTE_FLAG_LOOP_BACK } ) 191a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi @Retention(RetentionPolicy.SOURCE) 192a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public @interface RouteFlags {} 193a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 194a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 195a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Builder class for {@link AudioMix} objects 196a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * 197a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 1981b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @SystemApi 199a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public static class Builder { 200a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi private AudioMixingRule mRule = null; 201a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi private AudioFormat mFormat = null; 202a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi private int mRouteFlags = 0; 2035a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi private int mCallbackFlags = 0; 2044ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi // an AudioSystem.DEVICE_* value, not AudioDeviceInfo.TYPE_* 2054ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi private int mDeviceSystemType = AudioSystem.DEVICE_NONE; 206e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi private String mDeviceAddress = null; 207a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 208a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 209a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @hide 210a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Only used by AudioPolicyConfig, not a public API. 211a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 212a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi Builder() { } 213a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 214a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 215a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Construct an instance for the given {@link AudioMixingRule}. 216a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @param rule a non-null {@link AudioMixingRule} instance. 217a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @throws IllegalArgumentException 218a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 2191b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @SystemApi 220a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public Builder(AudioMixingRule rule) 221a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throws IllegalArgumentException { 222a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (rule == null) { 223a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throw new IllegalArgumentException("Illegal null AudioMixingRule argument"); 224a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 225a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mRule = rule; 226a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 227a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 228a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 229a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @hide 230a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Only used by AudioPolicyConfig, not a public API. 231a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @param rule 232a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @return the same Builder instance. 233a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @throws IllegalArgumentException 234a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 235e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi Builder setMixingRule(AudioMixingRule rule) 236a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throws IllegalArgumentException { 237a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (rule == null) { 238a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throw new IllegalArgumentException("Illegal null AudioMixingRule argument"); 239a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 240a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mRule = rule; 241a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi return this; 242a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 243a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 244a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 2455a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi * @hide 2465a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi * Only used by AudioPolicyConfig, not a public API. 2475a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi * @param callbackFlags which callbacks are called from native 2485a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi * @return the same Builder instance. 2495a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi * @throws IllegalArgumentException 2505a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi */ 251e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi Builder setCallbackFlags(int flags) throws IllegalArgumentException { 2525a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi if ((flags != 0) && ((flags & CALLBACK_FLAGS_ALL) == 0)) { 2535a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi throw new IllegalArgumentException("Illegal callback flags 0x" 2545a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi + Integer.toHexString(flags).toUpperCase()); 2555a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi } 2565a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi mCallbackFlags = flags; 2575a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi return this; 2585a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi } 2595a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi 2605a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi /** 261e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * @hide 262e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * Only used by AudioPolicyConfig, not a public API. 2634ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi * @param deviceType an AudioSystem.DEVICE_* value, not AudioDeviceInfo.TYPE_* 264e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * @param address 265e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * @return the same Builder instance. 266e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi */ 2674ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi Builder setDevice(int deviceType, String address) { 2684ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi mDeviceSystemType = deviceType; 269e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi mDeviceAddress = address; 270e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi return this; 271e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 272e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi 273e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi /** 274a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Sets the {@link AudioFormat} for the mix. 275a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @param format a non-null {@link AudioFormat} instance. 276a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @return the same Builder instance. 277a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @throws IllegalArgumentException 278a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 2791b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @SystemApi 280a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public Builder setFormat(AudioFormat format) 281a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throws IllegalArgumentException { 282a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (format == null) { 283a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throw new IllegalArgumentException("Illegal null AudioFormat argument"); 284a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 285a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mFormat = format; 286a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi return this; 287a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 288a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 289a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 290e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * Sets the routing behavior for the mix. If not set, routing behavior will default to 291e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * {@link AudioMix#ROUTE_FLAG_LOOP_BACK}. 292a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @param routeFlags one of {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, 293a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * {@link AudioMix#ROUTE_FLAG_RENDER} 294a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @return the same Builder instance. 295a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @throws IllegalArgumentException 296a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 2971b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @SystemApi 298a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public Builder setRouteFlags(@RouteFlags int routeFlags) 299a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throws IllegalArgumentException { 300a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (routeFlags == 0) { 301a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throw new IllegalArgumentException("Illegal empty route flags"); 302a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 303e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if ((routeFlags & ROUTE_FLAG_SUPPORTED) == 0) { 304a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throw new IllegalArgumentException("Invalid route flags 0x" 305e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi + Integer.toHexString(routeFlags) + "when configuring an AudioMix"); 306e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 307e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if ((routeFlags & ~ROUTE_FLAG_SUPPORTED) != 0) { 308e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi throw new IllegalArgumentException("Unknown route flags 0x" 309e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi + Integer.toHexString(routeFlags) + "when configuring an AudioMix"); 310a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 311a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mRouteFlags = routeFlags; 312a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi return this; 313a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 314a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi 315a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi /** 316e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * Sets the audio device used for playback. Cannot be used in the context of an audio 317e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * policy used to inject audio to be recorded, or in a mix whose route flags doesn't 318e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * specify {@link AudioMix#ROUTE_FLAG_RENDER}. 319e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * @param device a non-null AudioDeviceInfo describing the audio device to play the output 320e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * of this mix. 321e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * @return the same Builder instance 322e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi * @throws IllegalArgumentException 323e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi */ 324e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi @SystemApi 325e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi public Builder setDevice(@NonNull AudioDeviceInfo device) throws IllegalArgumentException { 326e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if (device == null) { 327e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi throw new IllegalArgumentException("Illegal null AudioDeviceInfo argument"); 328e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 329e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if (!device.isSink()) { 330e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi throw new IllegalArgumentException("Unsupported device type on mix, not a sink"); 331e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 3324ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi mDeviceSystemType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType()); 333e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi mDeviceAddress = device.getAddress(); 334e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi return this; 335e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 336e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi 337e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi /** 338a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Combines all of the settings and return a new {@link AudioMix} object. 339a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @return a new {@link AudioMix} object 340a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @throws IllegalArgumentException if no {@link AudioMixingRule} has been set. 341a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */ 3421b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi @SystemApi 343a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi public AudioMix build() throws IllegalArgumentException { 344a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (mRule == null) { 345a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi throw new IllegalArgumentException("Illegal null AudioMixingRule"); 346a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 347a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (mRouteFlags == 0) { 348e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi // no route flags set, use default as described in Builder.setRouteFlags(int) 349e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi mRouteFlags = ROUTE_FLAG_LOOP_BACK; 350e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 351e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi // can't do loop back AND render at same time in this implementation 352e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if (mRouteFlags == (ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK)) { 353e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi throw new IllegalArgumentException("Unsupported route behavior combination 0x" + 354e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi Integer.toHexString(mRouteFlags)); 355a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 356a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (mFormat == null) { 3571cbf9b3741ec486c3ffce08f145501eb1ca73640Glenn Kasten // FIXME Can we eliminate this? Will AudioMix work with an unspecified sample rate? 358a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi int rate = AudioSystem.getPrimaryOutputSamplingRate(); 359a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi if (rate <= 0) { 360a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi rate = 44100; 361a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 362a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi mFormat = new AudioFormat.Builder().setSampleRate(rate).build(); 363a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 3644ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi if ((mDeviceSystemType != AudioSystem.DEVICE_NONE) 3654ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi && (mDeviceSystemType != AudioSystem.DEVICE_OUT_REMOTE_SUBMIX) 3664ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi && (mDeviceSystemType != AudioSystem.DEVICE_IN_REMOTE_SUBMIX)) { 367e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if ((mRouteFlags & ROUTE_FLAG_RENDER) == 0) { 368e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi throw new IllegalArgumentException( 369e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi "Can't have audio device without flag ROUTE_FLAG_RENDER"); 370e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 371e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if (mRule.getTargetMixType() != AudioMix.MIX_TYPE_PLAYERS) { 372e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi throw new IllegalArgumentException("Unsupported device on non-playback mix"); 373e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 374e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } else { 375e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi if ((mRouteFlags & ROUTE_FLAG_RENDER) == ROUTE_FLAG_RENDER) { 376e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi throw new IllegalArgumentException( 377e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi "Can't have flag ROUTE_FLAG_RENDER without an audio device"); 378e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 3794ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi if ((mRouteFlags & ROUTE_FLAG_SUPPORTED) == ROUTE_FLAG_LOOP_BACK) { 3804ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi if (mRule.getTargetMixType() == MIX_TYPE_PLAYERS) { 3814ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi mDeviceSystemType = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 3824ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi } else if (mRule.getTargetMixType() == MIX_TYPE_RECORDERS) { 3834ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi mDeviceSystemType = AudioSystem.DEVICE_IN_REMOTE_SUBMIX; 3844ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi } else { 3854ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi throw new IllegalArgumentException("Unknown mixing rule type"); 3864ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi } 3874ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi } 388e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi } 3894ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi return new AudioMix(mRule, mFormat, mRouteFlags, mCallbackFlags, mDeviceSystemType, 390e8924115f9a57d35149da89c2a1bd920fdd0fe39Jean-Michel Trivi mDeviceAddress); 391a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 392a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi } 393a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi} 394