2 * Copyright (C) 2016 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package android.media;
19 import android.annotation.IntDef;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.util.Log;
24 import java.lang.annotation.Retention;
25 import java.lang.annotation.RetentionPolicy;
26 import java.util.ArrayList;
27 import java.util.Objects;
30 * The AudioRecordingConfiguration class collects the information describing an audio recording
32 * <p>Direct polling (see {@link AudioManager#getActiveRecordingConfigurations()}) or callback
33 * (see {@link AudioManager#registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler)}
34 * methods are ways to receive information about the current recording configuration of the device.
35 * <p>An audio recording configuration contains information about the recording format as used by
36 * the application ({@link #getClientFormat()}, as well as the recording format actually used by
37 * the device ({@link #getFormat()}). The two recording formats may, for instance, be at different
38 * sampling rates due to hardware limitations (e.g. application recording at 44.1kHz whereas the
39 * device always records at 48kHz, and the Android framework resamples for the application).
40 * <p>The configuration also contains the use case for which audio is recorded
41 * ({@link #getClientAudioSource()}), enabling the ability to distinguish between different
42 * activities such as ongoing voice recognition or camcorder recording.
45 public final class AudioRecordingConfiguration implements Parcelable {
46 private final static String TAG = new String("AudioRecordingConfiguration");
48 private final int mSessionId;
50 private final int mClientSource;
52 private final AudioFormat mDeviceFormat;
53 private final AudioFormat mClientFormat;
55 private final int mPatchHandle;
60 public AudioRecordingConfiguration(int session, int source, AudioFormat clientFormat,
61 AudioFormat devFormat, int patchHandle) {
63 mClientSource = source;
64 mClientFormat = clientFormat;
65 mDeviceFormat = devFormat;
66 mPatchHandle = patchHandle;
69 // matches the sources that return false in MediaRecorder.isSystemOnlyAudioSource(source)
72 MediaRecorder.AudioSource.DEFAULT,
73 MediaRecorder.AudioSource.MIC,
74 MediaRecorder.AudioSource.VOICE_UPLINK,
75 MediaRecorder.AudioSource.VOICE_DOWNLINK,
76 MediaRecorder.AudioSource.VOICE_CALL,
77 MediaRecorder.AudioSource.CAMCORDER,
78 MediaRecorder.AudioSource.VOICE_RECOGNITION,
79 MediaRecorder.AudioSource.VOICE_COMMUNICATION,
80 MediaRecorder.AudioSource.UNPROCESSED
82 @Retention(RetentionPolicy.SOURCE)
83 public @interface AudioSource {}
85 // documented return values match the sources that return false
86 // in MediaRecorder.isSystemOnlyAudioSource(source)
88 * Returns the audio source being used for the recording.
89 * @return one of {@link MediaRecorder.AudioSource#DEFAULT},
90 * {@link MediaRecorder.AudioSource#MIC},
91 * {@link MediaRecorder.AudioSource#VOICE_UPLINK},
92 * {@link MediaRecorder.AudioSource#VOICE_DOWNLINK},
93 * {@link MediaRecorder.AudioSource#VOICE_CALL},
94 * {@link MediaRecorder.AudioSource#CAMCORDER},
95 * {@link MediaRecorder.AudioSource#VOICE_RECOGNITION},
96 * {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION},
97 * {@link MediaRecorder.AudioSource#UNPROCESSED}.
99 public @AudioSource int getClientAudioSource() { return mClientSource; }
102 * Returns the session number of the recording, see {@link AudioRecord#getAudioSessionId()}.
103 * @return the session number.
105 public int getClientAudioSessionId() { return mSessionId; }
108 * Returns the audio format at which audio is recorded on this Android device.
109 * Note that it may differ from the client application recording format
110 * (see {@link #getClientFormat()}).
111 * @return the device recording format
113 public AudioFormat getFormat() { return mDeviceFormat; }
116 * Returns the audio format at which the client application is recording audio.
117 * Note that it may differ from the actual recording format (see {@link #getFormat()}).
118 * @return the recording format
120 public AudioFormat getClientFormat() { return mClientFormat; }
123 * Returns information about the audio input device used for this recording.
124 * @return the audio recording device or null if this information cannot be retrieved
126 public AudioDeviceInfo getAudioDevice() {
127 // build the AudioDeviceInfo from the patch handle
128 ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
129 if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) {
130 Log.e(TAG, "Error retrieving list of audio patches");
133 for (int i = 0 ; i < patches.size() ; i++) {
134 final AudioPatch patch = patches.get(i);
135 if (patch.id() == mPatchHandle) {
136 final AudioPortConfig[] sources = patch.sources();
137 if ((sources != null) && (sources.length > 0)) {
138 // not supporting multiple sources, so just look at the first source
139 final int devId = sources[0].port().id();
140 final AudioDeviceInfo[] devices =
141 AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_INPUTS);
142 for (int j = 0; j < devices.length; j++) {
143 if (devices[j].getId() == devId) {
148 // patch handle is unique, there won't be another with the same handle
152 Log.e(TAG, "Couldn't find device for recording, did recording end already?");
156 public static final Parcelable.Creator<AudioRecordingConfiguration> CREATOR
157 = new Parcelable.Creator<AudioRecordingConfiguration>() {
159 * Rebuilds an AudioRecordingConfiguration previously stored with writeToParcel().
160 * @param p Parcel object to read the AudioRecordingConfiguration from
161 * @return a new AudioRecordingConfiguration created from the data in the parcel
163 public AudioRecordingConfiguration createFromParcel(Parcel p) {
164 return new AudioRecordingConfiguration(p);
166 public AudioRecordingConfiguration[] newArray(int size) {
167 return new AudioRecordingConfiguration[size];
172 public int hashCode() {
173 return Objects.hash(mSessionId, mClientSource);
177 public int describeContents() {
182 public void writeToParcel(Parcel dest, int flags) {
183 dest.writeInt(mSessionId);
184 dest.writeInt(mClientSource);
185 mClientFormat.writeToParcel(dest, 0);
186 mDeviceFormat.writeToParcel(dest, 0);
187 dest.writeInt(mPatchHandle);
190 private AudioRecordingConfiguration(Parcel in) {
191 mSessionId = in.readInt();
192 mClientSource = in.readInt();
193 mClientFormat = AudioFormat.CREATOR.createFromParcel(in);
194 mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in);
195 mPatchHandle = in.readInt();
199 public boolean equals(Object o) {
200 if (this == o) return true;
201 if (o == null || !(o instanceof AudioRecordingConfiguration)) return false;
203 AudioRecordingConfiguration that = (AudioRecordingConfiguration) o;
205 return ((mSessionId == that.mSessionId)
206 && (mClientSource == that.mClientSource)
207 && (mPatchHandle == that.mPatchHandle)
208 && (mClientFormat.equals(that.mClientFormat))
209 && (mDeviceFormat.equals(that.mDeviceFormat)));