1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 package android.media;
18 
19 import android.annotation.IntDef;
20 
21 import java.lang.annotation.Retention;
22 import java.lang.annotation.RetentionPolicy;
23 
24 /**
25  * The AudioFormat class is used to access a number of audio format and
26  * channel configuration constants. They are for instance used
27  * in {@link AudioTrack} and {@link AudioRecord}.
28  *
29  */
30 public class AudioFormat {
31 
32     //---------------------------------------------------------
33     // Constants
34     //--------------------
35     /** Invalid audio data format */
36     public static final int ENCODING_INVALID = 0;
37     /** Default audio data format */
38     public static final int ENCODING_DEFAULT = 1;
39 
40     // These values must be kept in sync with core/jni/android_media_AudioFormat.h
41     /** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */
42     public static final int ENCODING_PCM_16BIT = 2;
43     /** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */
44     public static final int ENCODING_PCM_8BIT = 3;
45     /** Audio data format: single-precision floating-point per sample */
46     public static final int ENCODING_PCM_FLOAT = 4;
47     /** Audio data format: AC-3 compressed */
48     public static final int ENCODING_AC3 = 5;
49     /** Audio data format: E-AC-3 compressed */
50     public static final int ENCODING_E_AC3 = 6;
51 
52     /** Invalid audio channel configuration */
53     /** @deprecated use CHANNEL_INVALID instead  */
54     @Deprecated    public static final int CHANNEL_CONFIGURATION_INVALID   = 0;
55     /** Default audio channel configuration */
56     /** @deprecated use CHANNEL_OUT_DEFAULT or CHANNEL_IN_DEFAULT instead  */
57     @Deprecated    public static final int CHANNEL_CONFIGURATION_DEFAULT   = 1;
58     /** Mono audio configuration */
59     /** @deprecated use CHANNEL_OUT_MONO or CHANNEL_IN_MONO instead  */
60     @Deprecated    public static final int CHANNEL_CONFIGURATION_MONO      = 2;
61     /** Stereo (2 channel) audio configuration */
62     /** @deprecated use CHANNEL_OUT_STEREO or CHANNEL_IN_STEREO instead  */
63     @Deprecated    public static final int CHANNEL_CONFIGURATION_STEREO    = 3;
64 
65     /** Invalid audio channel mask */
66     public static final int CHANNEL_INVALID = 0;
67     /** Default audio channel mask */
68     public static final int CHANNEL_OUT_DEFAULT = 1;
69 
70     // Output channel mask definitions below are translated to the native values defined in
71     //  in /system/core/include/system/audio.h in the JNI code of AudioTrack
72     public static final int CHANNEL_OUT_FRONT_LEFT = 0x4;
73     public static final int CHANNEL_OUT_FRONT_RIGHT = 0x8;
74     public static final int CHANNEL_OUT_FRONT_CENTER = 0x10;
75     public static final int CHANNEL_OUT_LOW_FREQUENCY = 0x20;
76     public static final int CHANNEL_OUT_BACK_LEFT = 0x40;
77     public static final int CHANNEL_OUT_BACK_RIGHT = 0x80;
78     public static final int CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100;
79     public static final int CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200;
80     public static final int CHANNEL_OUT_BACK_CENTER = 0x400;
81     public static final int CHANNEL_OUT_SIDE_LEFT =         0x800;
82     public static final int CHANNEL_OUT_SIDE_RIGHT =       0x1000;
83     /** @hide */
84     public static final int CHANNEL_OUT_TOP_CENTER =       0x2000;
85     /** @hide */
86     public static final int CHANNEL_OUT_TOP_FRONT_LEFT =   0x4000;
87     /** @hide */
88     public static final int CHANNEL_OUT_TOP_FRONT_CENTER = 0x8000;
89     /** @hide */
90     public static final int CHANNEL_OUT_TOP_FRONT_RIGHT = 0x10000;
91     /** @hide */
92     public static final int CHANNEL_OUT_TOP_BACK_LEFT =   0x20000;
93     /** @hide */
94     public static final int CHANNEL_OUT_TOP_BACK_CENTER = 0x40000;
95     /** @hide */
96     public static final int CHANNEL_OUT_TOP_BACK_RIGHT =  0x80000;
97 
98     public static final int CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT;
99     public static final int CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT);
100     // aka QUAD_BACK
101     public static final int CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
102             CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT);
103     /** @hide */
104     public static final int CHANNEL_OUT_QUAD_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
105             CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT);
106     public static final int CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
107             CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER);
108     // aka 5POINT1_BACK
109     public static final int CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
110             CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT);
111     /** @hide */
112     public static final int CHANNEL_OUT_5POINT1_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
113             CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY |
114             CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT);
115     // TODO does this need an @deprecated ?
116     // different from AUDIO_CHANNEL_OUT_7POINT1
117     public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
118             CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
119             CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER);
120     /** @hide */
121     // matches AUDIO_CHANNEL_OUT_7POINT1
122     public static final int CHANNEL_OUT_7POINT1_SURROUND = (
123             CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_FRONT_RIGHT |
124             CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT |
125             CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
126             CHANNEL_OUT_LOW_FREQUENCY);
127     // CHANNEL_OUT_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_OUT_ALL
128 
129     /**
130      * @hide
131      * Return the input channel mask corresponding to an output channel mask.
132      * This can be used for submix rerouting for the mask of the recorder to map to that of the mix.
133      * @param outMask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT
134      * @return a combination of CHANNEL_IN_* definitions matching an output channel mask
135      * @throws IllegalArgumentException
136      */
inChannelMaskFromOutChannelMask(int outMask)137     public static int inChannelMaskFromOutChannelMask(int outMask) throws IllegalArgumentException {
138         if (outMask == CHANNEL_OUT_DEFAULT) {
139             throw new IllegalArgumentException(
140                     "Illegal CHANNEL_OUT_DEFAULT channel mask for input.");
141         }
142         switch (channelCountFromOutChannelMask(outMask)) {
143             case 1:
144                 return CHANNEL_IN_MONO;
145             case 2:
146                 return CHANNEL_IN_STEREO;
147             default:
148                 throw new IllegalArgumentException("Unsupported channel configuration for input.");
149         }
150     }
151 
152     /**
153      * @hide
154      * Return the number of channels from an input channel mask
155      * @param mask a combination of the CHANNEL_IN_* definitions, even CHANNEL_IN_DEFAULT
156      * @return number of channels for the mask
157      */
channelCountFromInChannelMask(int mask)158     public static int channelCountFromInChannelMask(int mask) {
159         return Integer.bitCount(mask);
160     }
161     /**
162      * @hide
163      * Return the number of channels from an output channel mask
164      * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT
165      * @return number of channels for the mask
166      */
channelCountFromOutChannelMask(int mask)167     public static int channelCountFromOutChannelMask(int mask) {
168         return Integer.bitCount(mask);
169     }
170     /**
171      * @hide
172      * Return a channel mask ready to be used by native code
173      * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT
174      * @return a native channel mask
175      */
convertChannelOutMaskToNativeMask(int javaMask)176     public static int convertChannelOutMaskToNativeMask(int javaMask) {
177         return (javaMask >> 2);
178     }
179 
180     /**
181      * @hide
182      * Return a java output channel mask
183      * @param mask a native channel mask
184      * @return a combination of the CHANNEL_OUT_* definitions
185      */
convertNativeChannelMaskToOutMask(int nativeMask)186     public static int convertNativeChannelMaskToOutMask(int nativeMask) {
187         return (nativeMask << 2);
188     }
189 
190     public static final int CHANNEL_IN_DEFAULT = 1;
191     // These directly match native
192     public static final int CHANNEL_IN_LEFT = 0x4;
193     public static final int CHANNEL_IN_RIGHT = 0x8;
194     public static final int CHANNEL_IN_FRONT = 0x10;
195     public static final int CHANNEL_IN_BACK = 0x20;
196     public static final int CHANNEL_IN_LEFT_PROCESSED = 0x40;
197     public static final int CHANNEL_IN_RIGHT_PROCESSED = 0x80;
198     public static final int CHANNEL_IN_FRONT_PROCESSED = 0x100;
199     public static final int CHANNEL_IN_BACK_PROCESSED = 0x200;
200     public static final int CHANNEL_IN_PRESSURE = 0x400;
201     public static final int CHANNEL_IN_X_AXIS = 0x800;
202     public static final int CHANNEL_IN_Y_AXIS = 0x1000;
203     public static final int CHANNEL_IN_Z_AXIS = 0x2000;
204     public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000;
205     public static final int CHANNEL_IN_VOICE_DNLINK = 0x8000;
206     public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT;
207     public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT);
208     /** @hide */
209     public static final int CHANNEL_IN_FRONT_BACK = CHANNEL_IN_FRONT | CHANNEL_IN_BACK;
210     // CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL
211 
212     /** @hide */
getBytesPerSample(int audioFormat)213     public static int getBytesPerSample(int audioFormat)
214     {
215         switch (audioFormat) {
216         case ENCODING_PCM_8BIT:
217             return 1;
218         case ENCODING_PCM_16BIT:
219         case ENCODING_DEFAULT:
220             return 2;
221         case ENCODING_PCM_FLOAT:
222             return 4;
223         case ENCODING_INVALID:
224         default:
225             throw new IllegalArgumentException("Bad audio format " + audioFormat);
226         }
227     }
228 
229     /** @hide */
isValidEncoding(int audioFormat)230     public static boolean isValidEncoding(int audioFormat)
231     {
232         switch (audioFormat) {
233         case ENCODING_PCM_8BIT:
234         case ENCODING_PCM_16BIT:
235         case ENCODING_PCM_FLOAT:
236         case ENCODING_AC3:
237         case ENCODING_E_AC3:
238             return true;
239         default:
240             return false;
241         }
242     }
243 
244     /** @hide */
isEncodingLinearPcm(int audioFormat)245     public static boolean isEncodingLinearPcm(int audioFormat)
246     {
247         switch (audioFormat) {
248         case ENCODING_PCM_8BIT:
249         case ENCODING_PCM_16BIT:
250         case ENCODING_PCM_FLOAT:
251         case ENCODING_DEFAULT:
252             return true;
253         case ENCODING_AC3:
254         case ENCODING_E_AC3:
255             return false;
256         case ENCODING_INVALID:
257         default:
258             throw new IllegalArgumentException("Bad audio format " + audioFormat);
259         }
260     }
261 
262     /** @removed */
AudioFormat()263     public AudioFormat()
264     {
265         throw new UnsupportedOperationException("There is no valid usage of this constructor");
266     }
267 
268     /**
269      * Private constructor with an ignored argument to differentiate from the removed default ctor
270      * @param ignoredArgument
271      */
AudioFormat(int ignoredArgument)272     private AudioFormat(int ignoredArgument) {
273     }
274 
275     /**
276      * Constructor used by the JNI
277      */
278     // Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this
279     // constructor
AudioFormat(int encoding, int sampleRate, int channelMask)280     private AudioFormat(int encoding, int sampleRate, int channelMask) {
281         mEncoding = encoding;
282         mSampleRate = sampleRate;
283         mChannelMask = channelMask;
284         mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_ENCODING |
285                 AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE |
286                 AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK;
287     }
288 
289     /** @hide */
290     public final static int AUDIO_FORMAT_HAS_PROPERTY_NONE = 0x0;
291     /** @hide */
292     public final static int AUDIO_FORMAT_HAS_PROPERTY_ENCODING = 0x1 << 0;
293     /** @hide */
294     public final static int AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE = 0x1 << 1;
295     /** @hide */
296     public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK = 0x1 << 2;
297 
298     private int mEncoding;
299     private int mSampleRate;
300     private int mChannelMask;
301     private int mPropertySetMask;
302 
303     /**
304      * Return the encoding.
305      * @return one of the values that can be set in {@link Builder#setEncoding(int)} or
306      * {@link AudioFormat#ENCODING_INVALID} if not set.
307      */
getEncoding()308     public int getEncoding() {
309         if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) == 0) {
310             return ENCODING_INVALID;
311         }
312         return mEncoding;
313     }
314 
315     /**
316      * Return the sample rate.
317      * @return one of the values that can be set in {@link Builder#setSampleRate(int)} or
318      * 0 if not set.
319      */
getSampleRate()320     public int getSampleRate() {
321         if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) == 0) {
322             return 0;
323         }
324         return mSampleRate;
325     }
326 
327     /**
328      * Return the channel mask.
329      * @return one of the values that can be set in {@link Builder#setChannelMask(int)} or
330      * {@link AudioFormat#CHANNEL_INVALID} if not set.
331      */
getChannelMask()332     public int getChannelMask() {
333         if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) == 0) {
334             return CHANNEL_INVALID;
335         }
336         return mChannelMask;
337     }
338 
339     /** @hide */
getPropertySetMask()340     public int getPropertySetMask() {
341         return mPropertySetMask;
342     }
343 
344     /**
345      * Builder class for {@link AudioFormat} objects.
346      * Use this class to configure and create an AudioFormat instance. By setting format
347      * characteristics such as audio encoding, channel mask or sample rate, you indicate which
348      * of those are to vary from the default behavior on this device wherever this audio format
349      * is used.
350      * <p>{@link AudioFormat} is for instance used in
351      * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}. In this
352      * constructor, every format characteristic set on the <code>Builder</code> (e.g. with
353      * {@link #setSampleRate(int)}) will alter the default values used by an
354      * <code>AudioTrack</code>. In this case for audio playback with <code>AudioTrack</code>, the
355      * sample rate set in the <code>Builder</code> would override the platform output sample rate
356      * which would otherwise be selected by default.
357      */
358     public static class Builder {
359         private int mEncoding = ENCODING_INVALID;
360         private int mSampleRate = 0;
361         private int mChannelMask = CHANNEL_INVALID;
362         private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE;
363 
364         /**
365          * Constructs a new Builder with none of the format characteristics set.
366          */
Builder()367         public Builder() {
368         }
369 
370         /**
371          * Constructs a new Builder from a given {@link AudioFormat}.
372          * @param af the {@link AudioFormat} object whose data will be reused in the new Builder.
373          */
Builder(AudioFormat af)374         public Builder(AudioFormat af) {
375             mEncoding = af.mEncoding;
376             mSampleRate = af.mSampleRate;
377             mChannelMask = af.mChannelMask;
378             mPropertySetMask = af.mPropertySetMask;
379         }
380 
381         /**
382          * Combines all of the format characteristics that have been set and return a new
383          * {@link AudioFormat} object.
384          * @return a new {@link AudioFormat} object
385          */
build()386         public AudioFormat build() {
387             AudioFormat af = new AudioFormat(1980/*ignored*/);
388             af.mEncoding = mEncoding;
389             af.mSampleRate = mSampleRate;
390             af.mChannelMask = mChannelMask;
391             af.mPropertySetMask = mPropertySetMask;
392             return af;
393         }
394 
395         /**
396          * Sets the data encoding format.
397          * @param encoding one of {@link AudioFormat#ENCODING_DEFAULT},
398          *     {@link AudioFormat#ENCODING_PCM_8BIT},
399          *     {@link AudioFormat#ENCODING_PCM_16BIT},
400          *     {@link AudioFormat#ENCODING_PCM_FLOAT},
401          *     {@link AudioFormat#ENCODING_AC3},
402          *     {@link AudioFormat#ENCODING_E_AC3}.
403          * @return the same Builder instance.
404          * @throws java.lang.IllegalArgumentException
405          */
setEncoding(@ncoding int encoding)406         public Builder setEncoding(@Encoding int encoding) throws IllegalArgumentException {
407             switch (encoding) {
408                 case ENCODING_DEFAULT:
409                     mEncoding = ENCODING_PCM_16BIT;
410                     break;
411                 case ENCODING_PCM_8BIT:
412                 case ENCODING_PCM_16BIT:
413                 case ENCODING_PCM_FLOAT:
414                 case ENCODING_AC3:
415                 case ENCODING_E_AC3:
416                     mEncoding = encoding;
417                     break;
418                 case ENCODING_INVALID:
419                 default:
420                     throw new IllegalArgumentException("Invalid encoding " + encoding);
421             }
422             mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_ENCODING;
423             return this;
424         }
425 
426         /**
427          * Sets the channel mask.
428          * @param channelMask describes the configuration of the audio channels.
429          *    <p>For output, the mask should be a combination of
430          *    {@link AudioFormat#CHANNEL_OUT_FRONT_LEFT},
431          *    {@link AudioFormat#CHANNEL_OUT_FRONT_CENTER},
432          *    {@link AudioFormat#CHANNEL_OUT_FRONT_RIGHT},
433          *    {@link AudioFormat#CHANNEL_OUT_SIDE_LEFT},
434          *    {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT},
435          *    {@link AudioFormat#CHANNEL_OUT_BACK_LEFT},
436          *    {@link AudioFormat#CHANNEL_OUT_BACK_RIGHT}.
437          *    <p>for input, the mask should be {@link AudioFormat#CHANNEL_IN_MONO} or
438          *    {@link AudioFormat#CHANNEL_IN_STEREO}.  {@link AudioFormat#CHANNEL_IN_MONO} is
439          *    guaranteed to work on all devices.
440          * @return the same Builder instance.
441          */
setChannelMask(int channelMask)442         public Builder setChannelMask(int channelMask) {
443             // only validated when used, with input or output context
444             mChannelMask = channelMask;
445             mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK;
446             return this;
447         }
448 
449         /**
450          * Sets the sample rate.
451          * @param sampleRate the sample rate expressed in Hz
452          * @return the same Builder instance.
453          * @throws java.lang.IllegalArgumentException
454          */
setSampleRate(int sampleRate)455         public Builder setSampleRate(int sampleRate) throws IllegalArgumentException {
456             if ((sampleRate <= 0) || (sampleRate > 192000)) {
457                 throw new IllegalArgumentException("Invalid sample rate " + sampleRate);
458             }
459             mSampleRate = sampleRate;
460             mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE;
461             return this;
462         }
463     }
464 
465     @Override
toString()466     public String toString () {
467         return new String("AudioFormat:"
468                 + " props=" + mPropertySetMask
469                 + " enc=" + mEncoding
470                 + " chan=0x" + Integer.toHexString(mChannelMask)
471                 + " rate=" + mSampleRate);
472     }
473 
474     /** @hide */
475     @IntDef({
476         ENCODING_DEFAULT,
477         ENCODING_PCM_8BIT,
478         ENCODING_PCM_16BIT,
479         ENCODING_PCM_FLOAT,
480         ENCODING_AC3,
481         ENCODING_E_AC3
482     })
483     @Retention(RetentionPolicy.SOURCE)
484     public @interface Encoding {}
485 
486 }
487