/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

/**
 * An AudioPortConfig contains a possible configuration of an audio port chosen
 * among all possible attributes described by an AudioPort.
 * An AudioPortConfig is created by AudioPort.buildConfiguration().
 * AudioPorts are used to specify the sources and sinks of a patch created
 * with AudioManager.connectAudioPatch().
 * Several specialized versions of AudioPortConfig exist to handle different categories of
 * audio ports and their specific attributes:
 * - AudioDevicePortConfig for input (e.g micropohone) and output devices (e.g speaker)
 * - AudioMixPortConfig for input or output streams of the audio framework.
 * @hide
 */

public class AudioPortConfig {
    final AudioPort mPort;
    private final int mSamplingRate;
    private final int mChannelMask;
    private final int mFormat;
    private final AudioGainConfig mGain;

    // mConfigMask indicates which fields in this configuration should be
    // taken into account. Used with AudioSystem.setAudioPortConfig()
    // framework use only.
    static final int SAMPLE_RATE  = 0x1;
    static final int CHANNEL_MASK = 0x2;
    static final int FORMAT       = 0x4;
    static final int GAIN         = 0x8;
    int mConfigMask;

    AudioPortConfig(AudioPort port, int samplingRate, int channelMask, int format,
            AudioGainConfig gain) {
        mPort = port;
        mSamplingRate = samplingRate;
        mChannelMask = channelMask;
        mFormat = format;
        mGain = gain;
        mConfigMask = 0;
    }

    /**
     * Returns the audio port this AudioPortConfig is issued from.
     */
    public AudioPort port() {
        return mPort;
    }

    /**
     * Sampling rate configured for this AudioPortConfig.
     */
    public int samplingRate() {
        return mSamplingRate;
    }

    /**
     * Channel mask configuration (e.g AudioFormat.CHANNEL_CONFIGURATION_STEREO).
     */
    public int channelMask() {
        return mChannelMask;
    }

    /**
     * Audio format configuration (e.g AudioFormat.ENCODING_PCM_16BIT).
     */
    public int format() {
        return mFormat;
    }

    /**
     * The gain configuration if this port supports gain control, null otherwise
     * @see AudioGainConfig.
     */
    public AudioGainConfig gain() {
        return mGain;
    }

    @Override
    public String toString() {
        return "{mPort:" + mPort
                + ", mSamplingRate:" + mSamplingRate
                + ", mChannelMask: " + mChannelMask
                + ", mFormat:" + mFormat
                + ", mGain:" + mGain
                + "}";
    }
}
