Merge "Allow sample rate UNSPECIFIED to mean a route-dependent value" into nyc-dev
am: 642a4f5b66
* commit '642a4f5b66841788ffce5cf1d81ba744265db174':
Allow sample rate UNSPECIFIED to mean a route-dependent value
This commit is contained in:
@@ -19767,6 +19767,7 @@ package android.media {
|
|||||||
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
|
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
|
||||||
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
|
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
|
||||||
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
||||||
|
field public static final int SAMPLE_RATE_UNSPECIFIED = 0; // 0x0
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AudioFormat.Builder {
|
public static class AudioFormat.Builder {
|
||||||
|
|||||||
@@ -21263,6 +21263,7 @@ package android.media {
|
|||||||
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
|
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
|
||||||
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
|
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
|
||||||
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
||||||
|
field public static final int SAMPLE_RATE_UNSPECIFIED = 0; // 0x0
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AudioFormat.Builder {
|
public static class AudioFormat.Builder {
|
||||||
|
|||||||
@@ -19776,6 +19776,7 @@ package android.media {
|
|||||||
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
|
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
|
||||||
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
|
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
|
||||||
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
|
||||||
|
field public static final int SAMPLE_RATE_UNSPECIFIED = 0; // 0x0
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AudioFormat.Builder {
|
public static class AudioFormat.Builder {
|
||||||
|
|||||||
@@ -180,9 +180,13 @@ static sp<AudioRecord> setAudioRecord(JNIEnv* env, jobject thiz, const sp<AudioR
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
static jint
|
static jint
|
||||||
android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||||
jobject jaa, jint sampleRateInHertz, jint channelMask, jint channelIndexMask,
|
jobject jaa, jintArray jSampleRate, jint channelMask, jint channelIndexMask,
|
||||||
jint audioFormat, jint buffSizeInBytes, jintArray jSession, jstring opPackageName)
|
jint audioFormat, jint buffSizeInBytes, jintArray jSession, jstring opPackageName)
|
||||||
{
|
{
|
||||||
|
jint elements[1];
|
||||||
|
env->GetIntArrayRegion(jSampleRate, 0, 1, elements);
|
||||||
|
int sampleRateInHertz = elements[0];
|
||||||
|
|
||||||
//ALOGV(">> Entering android_media_AudioRecord_setup");
|
//ALOGV(">> Entering android_media_AudioRecord_setup");
|
||||||
//ALOGV("sampleRate=%d, audioFormat=%d, channel mask=%x, buffSizeInBytes=%d",
|
//ALOGV("sampleRate=%d, audioFormat=%d, channel mask=%x, buffSizeInBytes=%d",
|
||||||
// sampleRateInHertz, audioFormat, channelMask, buffSizeInBytes);
|
// sampleRateInHertz, audioFormat, channelMask, buffSizeInBytes);
|
||||||
@@ -304,6 +308,11 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
|||||||
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
|
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
|
||||||
nSession = NULL;
|
nSession = NULL;
|
||||||
|
|
||||||
|
{
|
||||||
|
const jint elements[1] = { (jint) lpRecorder->getSampleRate() };
|
||||||
|
env->SetIntArrayRegion(jSampleRate, 0, 1, elements);
|
||||||
|
}
|
||||||
|
|
||||||
{ // scope for the lock
|
{ // scope for the lock
|
||||||
Mutex::Autolock l(sLock);
|
Mutex::Autolock l(sLock);
|
||||||
sAudioRecordCallBackCookies.add(lpCallbackData);
|
sAudioRecordCallBackCookies.add(lpCallbackData);
|
||||||
@@ -717,7 +726,7 @@ static const JNINativeMethod gMethods[] = {
|
|||||||
// name, signature, funcPtr
|
// name, signature, funcPtr
|
||||||
{"native_start", "(II)I", (void *)android_media_AudioRecord_start},
|
{"native_start", "(II)I", (void *)android_media_AudioRecord_start},
|
||||||
{"native_stop", "()V", (void *)android_media_AudioRecord_stop},
|
{"native_stop", "()V", (void *)android_media_AudioRecord_stop},
|
||||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;IIIII[ILjava/lang/String;)I",
|
{"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILjava/lang/String;)I",
|
||||||
(void *)android_media_AudioRecord_setup},
|
(void *)android_media_AudioRecord_setup},
|
||||||
{"native_finalize", "()V", (void *)android_media_AudioRecord_finalize},
|
{"native_finalize", "()V", (void *)android_media_AudioRecord_finalize},
|
||||||
{"native_release", "()V", (void *)android_media_AudioRecord_release},
|
{"native_release", "()V", (void *)android_media_AudioRecord_release},
|
||||||
|
|||||||
@@ -215,9 +215,13 @@ static inline audio_channel_mask_t nativeChannelMaskFromJavaChannelMasks(
|
|||||||
static jint
|
static jint
|
||||||
android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||||
jobject jaa,
|
jobject jaa,
|
||||||
jint sampleRateInHertz, jint channelPositionMask, jint channelIndexMask,
|
jintArray jSampleRate, jint channelPositionMask, jint channelIndexMask,
|
||||||
jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession) {
|
jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession) {
|
||||||
|
|
||||||
|
jint elements[1];
|
||||||
|
env->GetIntArrayRegion(jSampleRate, 0, 1, elements);
|
||||||
|
int sampleRateInHertz = elements[0];
|
||||||
|
|
||||||
ALOGV("sampleRate=%d, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d",
|
ALOGV("sampleRate=%d, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d",
|
||||||
sampleRateInHertz, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes);
|
sampleRateInHertz, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes);
|
||||||
|
|
||||||
@@ -370,6 +374,11 @@ android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
|||||||
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
|
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
|
||||||
nSession = NULL;
|
nSession = NULL;
|
||||||
|
|
||||||
|
{
|
||||||
|
const jint elements[1] = { (jint) lpTrack->getSampleRate() };
|
||||||
|
env->SetIntArrayRegion(jSampleRate, 0, 1, elements);
|
||||||
|
}
|
||||||
|
|
||||||
{ // scope for the lock
|
{ // scope for the lock
|
||||||
Mutex::Autolock l(sLock);
|
Mutex::Autolock l(sLock);
|
||||||
sAudioTrackCallBackCookies.add(&lpJniStorage->mCallbackData);
|
sAudioTrackCallBackCookies.add(&lpJniStorage->mCallbackData);
|
||||||
@@ -1114,7 +1123,7 @@ static const JNINativeMethod gMethods[] = {
|
|||||||
{"native_stop", "()V", (void *)android_media_AudioTrack_stop},
|
{"native_stop", "()V", (void *)android_media_AudioTrack_stop},
|
||||||
{"native_pause", "()V", (void *)android_media_AudioTrack_pause},
|
{"native_pause", "()V", (void *)android_media_AudioTrack_pause},
|
||||||
{"native_flush", "()V", (void *)android_media_AudioTrack_flush},
|
{"native_flush", "()V", (void *)android_media_AudioTrack_flush},
|
||||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;IIIIII[I)I",
|
{"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[I)I",
|
||||||
(void *)android_media_AudioTrack_setup},
|
(void *)android_media_AudioTrack_setup},
|
||||||
{"native_finalize", "()V", (void *)android_media_AudioTrack_finalize},
|
{"native_finalize", "()V", (void *)android_media_AudioTrack_finalize},
|
||||||
{"native_release", "()V", (void *)android_media_AudioTrack_release},
|
{"native_release", "()V", (void *)android_media_AudioTrack_release},
|
||||||
|
|||||||
@@ -335,6 +335,24 @@ public class AudioFormat implements Parcelable {
|
|||||||
CHANNEL_OUT_LOW_FREQUENCY);
|
CHANNEL_OUT_LOW_FREQUENCY);
|
||||||
// CHANNEL_OUT_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_OUT_ALL
|
// CHANNEL_OUT_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_OUT_ALL
|
||||||
|
|
||||||
|
/** Minimum value for sample rate,
|
||||||
|
* assuming AudioTrack and AudioRecord share the same limitations.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
// never unhide
|
||||||
|
public static final int SAMPLE_RATE_HZ_MIN = 4000;
|
||||||
|
/** Maximum value for sample rate,
|
||||||
|
* assuming AudioTrack and AudioRecord share the same limitations.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
// never unhide
|
||||||
|
public static final int SAMPLE_RATE_HZ_MAX = 192000;
|
||||||
|
/** Sample rate will be a route-dependent value.
|
||||||
|
* For AudioTrack, it is usually the sink sample rate,
|
||||||
|
* and for AudioRecord it is usually the source sample rate.
|
||||||
|
*/
|
||||||
|
public static final int SAMPLE_RATE_UNSPECIFIED = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
* Return the input channel mask corresponding to an output channel mask.
|
* Return the input channel mask corresponding to an output channel mask.
|
||||||
@@ -561,7 +579,7 @@ public class AudioFormat implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used by the JNI
|
* Constructor used by the JNI. Parameters are not checked for validity.
|
||||||
*/
|
*/
|
||||||
// Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this
|
// Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this
|
||||||
// constructor
|
// constructor
|
||||||
@@ -610,12 +628,9 @@ public class AudioFormat implements Parcelable {
|
|||||||
/**
|
/**
|
||||||
* Return the sample rate.
|
* Return the sample rate.
|
||||||
* @return one of the values that can be set in {@link Builder#setSampleRate(int)} or
|
* @return one of the values that can be set in {@link Builder#setSampleRate(int)} or
|
||||||
* 0 if not set.
|
* {@link #SAMPLE_RATE_UNSPECIFIED} if not set.
|
||||||
*/
|
*/
|
||||||
public int getSampleRate() {
|
public int getSampleRate() {
|
||||||
if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return mSampleRate;
|
return mSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,7 +702,7 @@ public class AudioFormat implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private int mEncoding = ENCODING_INVALID;
|
private int mEncoding = ENCODING_INVALID;
|
||||||
private int mSampleRate = 0;
|
private int mSampleRate = SAMPLE_RATE_UNSPECIFIED;
|
||||||
private int mChannelMask = CHANNEL_INVALID;
|
private int mChannelMask = CHANNEL_INVALID;
|
||||||
private int mChannelIndexMask = 0;
|
private int mChannelIndexMask = 0;
|
||||||
private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE;
|
private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE;
|
||||||
@@ -718,6 +733,8 @@ public class AudioFormat implements Parcelable {
|
|||||||
public AudioFormat build() {
|
public AudioFormat build() {
|
||||||
AudioFormat af = new AudioFormat(1980/*ignored*/);
|
AudioFormat af = new AudioFormat(1980/*ignored*/);
|
||||||
af.mEncoding = mEncoding;
|
af.mEncoding = mEncoding;
|
||||||
|
// not calling setSampleRate is equivalent to calling
|
||||||
|
// setSampleRate(SAMPLE_RATE_UNSPECIFIED)
|
||||||
af.mSampleRate = mSampleRate;
|
af.mSampleRate = mSampleRate;
|
||||||
af.mChannelMask = mChannelMask;
|
af.mChannelMask = mChannelMask;
|
||||||
af.mChannelIndexMask = mChannelIndexMask;
|
af.mChannelIndexMask = mChannelIndexMask;
|
||||||
@@ -795,7 +812,7 @@ public class AudioFormat implements Parcelable {
|
|||||||
* are specified but do not have the same channel count.
|
* are specified but do not have the same channel count.
|
||||||
*/
|
*/
|
||||||
public @NonNull Builder setChannelMask(int channelMask) {
|
public @NonNull Builder setChannelMask(int channelMask) {
|
||||||
if (channelMask == 0) {
|
if (channelMask == CHANNEL_INVALID) {
|
||||||
throw new IllegalArgumentException("Invalid zero channel mask");
|
throw new IllegalArgumentException("Invalid zero channel mask");
|
||||||
} else if (/* channelMask != 0 && */ mChannelIndexMask != 0 &&
|
} else if (/* channelMask != 0 && */ mChannelIndexMask != 0 &&
|
||||||
Integer.bitCount(channelMask) != Integer.bitCount(mChannelIndexMask)) {
|
Integer.bitCount(channelMask) != Integer.bitCount(mChannelIndexMask)) {
|
||||||
@@ -867,7 +884,11 @@ public class AudioFormat implements Parcelable {
|
|||||||
* @throws java.lang.IllegalArgumentException
|
* @throws java.lang.IllegalArgumentException
|
||||||
*/
|
*/
|
||||||
public Builder setSampleRate(int sampleRate) throws IllegalArgumentException {
|
public Builder setSampleRate(int sampleRate) throws IllegalArgumentException {
|
||||||
if ((sampleRate <= 0) || (sampleRate > 192000)) {
|
// TODO Consider whether to keep the MIN and MAX range checks here.
|
||||||
|
// It is not necessary and poses the problem of defining the limits independently from
|
||||||
|
// native implementation or platform capabilities.
|
||||||
|
if (((sampleRate < SAMPLE_RATE_HZ_MIN) || (sampleRate > SAMPLE_RATE_HZ_MAX)) &&
|
||||||
|
sampleRate != SAMPLE_RATE_UNSPECIFIED) {
|
||||||
throw new IllegalArgumentException("Invalid sample rate " + sampleRate);
|
throw new IllegalArgumentException("Invalid sample rate " + sampleRate);
|
||||||
}
|
}
|
||||||
mSampleRate = sampleRate;
|
mSampleRate = sampleRate;
|
||||||
|
|||||||
@@ -3321,6 +3321,7 @@ public class AudioManager {
|
|||||||
* Used as a key for {@link #getProperty} to request the native or optimal output sample rate
|
* Used as a key for {@link #getProperty} to request the native or optimal output sample rate
|
||||||
* for this device's primary output stream, in decimal Hz.
|
* for this device's primary output stream, in decimal Hz.
|
||||||
*/
|
*/
|
||||||
|
// FIXME Deprecate
|
||||||
public static final String PROPERTY_OUTPUT_SAMPLE_RATE =
|
public static final String PROPERTY_OUTPUT_SAMPLE_RATE =
|
||||||
"android.media.property.OUTPUT_SAMPLE_RATE";
|
"android.media.property.OUTPUT_SAMPLE_RATE";
|
||||||
|
|
||||||
@@ -3328,6 +3329,7 @@ public class AudioManager {
|
|||||||
* Used as a key for {@link #getProperty} to request the native or optimal output buffer size
|
* Used as a key for {@link #getProperty} to request the native or optimal output buffer size
|
||||||
* for this device's primary output stream, in decimal PCM frames.
|
* for this device's primary output stream, in decimal PCM frames.
|
||||||
*/
|
*/
|
||||||
|
// FIXME Deprecate
|
||||||
public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER =
|
public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER =
|
||||||
"android.media.property.OUTPUT_FRAMES_PER_BUFFER";
|
"android.media.property.OUTPUT_FRAMES_PER_BUFFER";
|
||||||
|
|
||||||
|
|||||||
@@ -57,10 +57,6 @@ public class AudioRecord implements AudioRouting
|
|||||||
// Constants
|
// Constants
|
||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
/** Minimum value for sample rate */
|
|
||||||
private static final int SAMPLE_RATE_HZ_MIN = 4000;
|
|
||||||
/** Maximum value for sample rate */
|
|
||||||
private static final int SAMPLE_RATE_HZ_MAX = 192000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* indicates AudioRecord state is not successfully initialized.
|
* indicates AudioRecord state is not successfully initialized.
|
||||||
@@ -168,8 +164,9 @@ public class AudioRecord implements AudioRouting
|
|||||||
//--------------------
|
//--------------------
|
||||||
/**
|
/**
|
||||||
* The audio data sampling rate in Hz.
|
* The audio data sampling rate in Hz.
|
||||||
|
* Never {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED}.
|
||||||
*/
|
*/
|
||||||
private int mSampleRate;
|
private int mSampleRate; // initialized by all constructors via audioParamCheck()
|
||||||
/**
|
/**
|
||||||
* The number of input audio channels (1 is mono, 2 is stereo)
|
* The number of input audio channels (1 is mono, 2 is stereo)
|
||||||
*/
|
*/
|
||||||
@@ -251,6 +248,9 @@ public class AudioRecord implements AudioRouting
|
|||||||
* @param sampleRateInHz the sample rate expressed in Hertz. 44100Hz is currently the only
|
* @param sampleRateInHz the sample rate expressed in Hertz. 44100Hz is currently the only
|
||||||
* rate that is guaranteed to work on all devices, but other rates such as 22050,
|
* rate that is guaranteed to work on all devices, but other rates such as 22050,
|
||||||
* 16000, and 11025 may work on some devices.
|
* 16000, and 11025 may work on some devices.
|
||||||
|
* {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
|
||||||
|
* which is usually the sample rate of the source.
|
||||||
|
* {@link #getSampleRate()} can be used to retrieve the actual sample rate chosen.
|
||||||
* @param channelConfig describes the configuration of the audio channels.
|
* @param channelConfig describes the configuration of the audio channels.
|
||||||
* See {@link AudioFormat#CHANNEL_IN_MONO} and
|
* See {@link AudioFormat#CHANNEL_IN_MONO} and
|
||||||
* {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is guaranteed
|
* {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is guaranteed
|
||||||
@@ -337,16 +337,9 @@ public class AudioRecord implements AudioRouting
|
|||||||
mAudioAttributes = attributes;
|
mAudioAttributes = attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rate = 0;
|
int rate = format.getSampleRate();
|
||||||
if ((format.getPropertySetMask()
|
if (rate == AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
|
||||||
& AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0)
|
rate = 0;
|
||||||
{
|
|
||||||
rate = format.getSampleRate();
|
|
||||||
} else {
|
|
||||||
rate = AudioSystem.getPrimaryOutputSamplingRate();
|
|
||||||
if (rate <= 0) {
|
|
||||||
rate = 44100;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int encoding = AudioFormat.ENCODING_DEFAULT;
|
int encoding = AudioFormat.ENCODING_DEFAULT;
|
||||||
@@ -373,12 +366,13 @@ public class AudioRecord implements AudioRouting
|
|||||||
|
|
||||||
audioBuffSizeCheck(bufferSizeInBytes);
|
audioBuffSizeCheck(bufferSizeInBytes);
|
||||||
|
|
||||||
|
int[] sampleRate = new int[] {mSampleRate};
|
||||||
int[] session = new int[1];
|
int[] session = new int[1];
|
||||||
session[0] = sessionId;
|
session[0] = sessionId;
|
||||||
//TODO: update native initialization when information about hardware init failure
|
//TODO: update native initialization when information about hardware init failure
|
||||||
// due to capture device already open is available.
|
// due to capture device already open is available.
|
||||||
int initResult = native_setup( new WeakReference<AudioRecord>(this),
|
int initResult = native_setup( new WeakReference<AudioRecord>(this),
|
||||||
mAudioAttributes, mSampleRate, mChannelMask, mChannelIndexMask,
|
mAudioAttributes, sampleRate, mChannelMask, mChannelIndexMask,
|
||||||
mAudioFormat, mNativeBufferSizeInBytes,
|
mAudioFormat, mNativeBufferSizeInBytes,
|
||||||
session, ActivityThread.currentOpPackageName());
|
session, ActivityThread.currentOpPackageName());
|
||||||
if (initResult != SUCCESS) {
|
if (initResult != SUCCESS) {
|
||||||
@@ -386,6 +380,7 @@ public class AudioRecord implements AudioRouting
|
|||||||
return; // with mState == STATE_UNINITIALIZED
|
return; // with mState == STATE_UNINITIALIZED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSampleRate = sampleRate[0];
|
||||||
mSessionId = session[0];
|
mSessionId = session[0];
|
||||||
|
|
||||||
mState = STATE_INITIALIZED;
|
mState = STATE_INITIALIZED;
|
||||||
@@ -623,6 +618,7 @@ public class AudioRecord implements AudioRouting
|
|||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
// postconditions:
|
// postconditions:
|
||||||
// mRecordSource is valid
|
// mRecordSource is valid
|
||||||
// mAudioFormat is valid
|
// mAudioFormat is valid
|
||||||
@@ -642,7 +638,9 @@ public class AudioRecord implements AudioRouting
|
|||||||
|
|
||||||
//--------------
|
//--------------
|
||||||
// sample rate
|
// sample rate
|
||||||
if ((sampleRateInHz < SAMPLE_RATE_HZ_MIN) || (sampleRateInHz > SAMPLE_RATE_HZ_MAX)) {
|
if ((sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN ||
|
||||||
|
sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) &&
|
||||||
|
sampleRateInHz != AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
|
||||||
throw new IllegalArgumentException(sampleRateInHz
|
throw new IllegalArgumentException(sampleRateInHz
|
||||||
+ "Hz is not a supported sample rate.");
|
+ "Hz is not a supported sample rate.");
|
||||||
}
|
}
|
||||||
@@ -714,7 +712,11 @@ public class AudioRecord implements AudioRouting
|
|||||||
// Getters
|
// Getters
|
||||||
//--------------------
|
//--------------------
|
||||||
/**
|
/**
|
||||||
* Returns the configured audio data sample rate in Hz
|
* Returns the configured audio sink sample rate in Hz.
|
||||||
|
* The sink sample rate never changes after construction.
|
||||||
|
* If the constructor had a specific sample rate, then the sink sample rate is that value.
|
||||||
|
* If the constructor had {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED},
|
||||||
|
* then the sink sample rate is a route-dependent default value based on the source [sic].
|
||||||
*/
|
*/
|
||||||
public int getSampleRate() {
|
public int getSampleRate() {
|
||||||
return mSampleRate;
|
return mSampleRate;
|
||||||
@@ -861,6 +863,7 @@ public class AudioRecord implements AudioRouting
|
|||||||
* See {@link #AudioRecord(int, int, int, int, int)} for more information on valid
|
* See {@link #AudioRecord(int, int, int, int, int)} for more information on valid
|
||||||
* configuration values.
|
* configuration values.
|
||||||
* @param sampleRateInHz the sample rate expressed in Hertz.
|
* @param sampleRateInHz the sample rate expressed in Hertz.
|
||||||
|
* {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} is not permitted.
|
||||||
* @param channelConfig describes the configuration of the audio channels.
|
* @param channelConfig describes the configuration of the audio channels.
|
||||||
* See {@link AudioFormat#CHANNEL_IN_MONO} and
|
* See {@link AudioFormat#CHANNEL_IN_MONO} and
|
||||||
* {@link AudioFormat#CHANNEL_IN_STEREO}
|
* {@link AudioFormat#CHANNEL_IN_STEREO}
|
||||||
@@ -1708,7 +1711,7 @@ public class AudioRecord implements AudioRouting
|
|||||||
|
|
||||||
private native final int native_setup(Object audiorecord_this,
|
private native final int native_setup(Object audiorecord_this,
|
||||||
Object /*AudioAttributes*/ attributes,
|
Object /*AudioAttributes*/ attributes,
|
||||||
int sampleRate, int channelMask, int channelIndexMask, int audioFormat,
|
int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
|
||||||
int buffSizeInBytes, int[] sessionId, String opPackageName);
|
int buffSizeInBytes, int[] sessionId, String opPackageName);
|
||||||
|
|
||||||
// TODO remove: implementation calls directly into implementation of native_release()
|
// TODO remove: implementation calls directly into implementation of native_release()
|
||||||
|
|||||||
@@ -91,11 +91,6 @@ public class AudioTrack implements AudioRouting
|
|||||||
*/
|
*/
|
||||||
private static final float GAIN_MAX = 1.0f;
|
private static final float GAIN_MAX = 1.0f;
|
||||||
|
|
||||||
/** Minimum value for sample rate */
|
|
||||||
private static final int SAMPLE_RATE_HZ_MIN = 4000;
|
|
||||||
/** Maximum value for sample rate */
|
|
||||||
private static final int SAMPLE_RATE_HZ_MAX = 192000;
|
|
||||||
|
|
||||||
/** Maximum value for AudioTrack channel count
|
/** Maximum value for AudioTrack channel count
|
||||||
* @hide public for MediaCode only, do not un-hide or change to a numeric literal
|
* @hide public for MediaCode only, do not un-hide or change to a numeric literal
|
||||||
*/
|
*/
|
||||||
@@ -254,6 +249,7 @@ public class AudioTrack implements AudioRouting
|
|||||||
private final Looper mInitializationLooper;
|
private final Looper mInitializationLooper;
|
||||||
/**
|
/**
|
||||||
* The audio data source sampling rate in Hz.
|
* The audio data source sampling rate in Hz.
|
||||||
|
* Never {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED}.
|
||||||
*/
|
*/
|
||||||
private int mSampleRate; // initialized by all constructors via audioParamCheck()
|
private int mSampleRate; // initialized by all constructors via audioParamCheck()
|
||||||
/**
|
/**
|
||||||
@@ -340,6 +336,9 @@ public class AudioTrack implements AudioRouting
|
|||||||
* {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
|
* {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
|
||||||
* {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
|
* {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
|
||||||
* @param sampleRateInHz the initial source sample rate expressed in Hz.
|
* @param sampleRateInHz the initial source sample rate expressed in Hz.
|
||||||
|
* {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
|
||||||
|
* which is usually the sample rate of the sink.
|
||||||
|
* {@link #getSampleRate()} can be used to retrieve the actual sample rate chosen.
|
||||||
* @param channelConfig describes the configuration of the audio channels.
|
* @param channelConfig describes the configuration of the audio channels.
|
||||||
* See {@link AudioFormat#CHANNEL_OUT_MONO} and
|
* See {@link AudioFormat#CHANNEL_OUT_MONO} and
|
||||||
* {@link AudioFormat#CHANNEL_OUT_STEREO}
|
* {@link AudioFormat#CHANNEL_OUT_STEREO}
|
||||||
@@ -389,6 +388,8 @@ public class AudioTrack implements AudioRouting
|
|||||||
* {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
|
* {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
|
||||||
* {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
|
* {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
|
||||||
* @param sampleRateInHz the initial source sample rate expressed in Hz.
|
* @param sampleRateInHz the initial source sample rate expressed in Hz.
|
||||||
|
* {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
|
||||||
|
* which is usually the sample rate of the sink.
|
||||||
* @param channelConfig describes the configuration of the audio channels.
|
* @param channelConfig describes the configuration of the audio channels.
|
||||||
* See {@link AudioFormat#CHANNEL_OUT_MONO} and
|
* See {@link AudioFormat#CHANNEL_OUT_MONO} and
|
||||||
* {@link AudioFormat#CHANNEL_OUT_STEREO}
|
* {@link AudioFormat#CHANNEL_OUT_STEREO}
|
||||||
@@ -461,16 +462,11 @@ public class AudioTrack implements AudioRouting
|
|||||||
looper = Looper.getMainLooper();
|
looper = Looper.getMainLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
int rate = 0;
|
int rate = format.getSampleRate();
|
||||||
if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0)
|
if (rate == AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
|
||||||
{
|
rate = 0;
|
||||||
rate = format.getSampleRate();
|
|
||||||
} else {
|
|
||||||
rate = AudioSystem.getPrimaryOutputSamplingRate();
|
|
||||||
if (rate <= 0) {
|
|
||||||
rate = 44100;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int channelIndexMask = 0;
|
int channelIndexMask = 0;
|
||||||
if ((format.getPropertySetMask()
|
if ((format.getPropertySetMask()
|
||||||
& AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0) {
|
& AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0) {
|
||||||
@@ -503,17 +499,19 @@ public class AudioTrack implements AudioRouting
|
|||||||
throw new IllegalArgumentException("Invalid audio session ID: "+sessionId);
|
throw new IllegalArgumentException("Invalid audio session ID: "+sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int[] sampleRate = new int[] {mSampleRate};
|
||||||
int[] session = new int[1];
|
int[] session = new int[1];
|
||||||
session[0] = sessionId;
|
session[0] = sessionId;
|
||||||
// native initialization
|
// native initialization
|
||||||
int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
|
int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
|
||||||
mSampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
|
sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
|
||||||
mNativeBufferSizeInBytes, mDataLoadMode, session);
|
mNativeBufferSizeInBytes, mDataLoadMode, session);
|
||||||
if (initResult != SUCCESS) {
|
if (initResult != SUCCESS) {
|
||||||
loge("Error code "+initResult+" when initializing AudioTrack.");
|
loge("Error code "+initResult+" when initializing AudioTrack.");
|
||||||
return; // with mState == STATE_UNINITIALIZED
|
return; // with mState == STATE_UNINITIALIZED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSampleRate = sampleRate[0];
|
||||||
mSessionId = session[0];
|
mSessionId = session[0];
|
||||||
|
|
||||||
if (mDataLoadMode == MODE_STATIC) {
|
if (mDataLoadMode == MODE_STATIC) {
|
||||||
@@ -712,7 +710,7 @@ public class AudioTrack implements AudioRouting
|
|||||||
if (mFormat == null) {
|
if (mFormat == null) {
|
||||||
mFormat = new AudioFormat.Builder()
|
mFormat = new AudioFormat.Builder()
|
||||||
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
|
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
|
||||||
.setSampleRate(AudioSystem.getPrimaryOutputSamplingRate())
|
//.setSampleRate(AudioFormat.SAMPLE_RATE_UNSPECIFIED)
|
||||||
.setEncoding(AudioFormat.ENCODING_DEFAULT)
|
.setEncoding(AudioFormat.ENCODING_DEFAULT)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@@ -762,7 +760,9 @@ public class AudioTrack implements AudioRouting
|
|||||||
int audioFormat, int mode) {
|
int audioFormat, int mode) {
|
||||||
//--------------
|
//--------------
|
||||||
// sample rate, note these values are subject to change
|
// sample rate, note these values are subject to change
|
||||||
if (sampleRateInHz < SAMPLE_RATE_HZ_MIN || sampleRateInHz > SAMPLE_RATE_HZ_MAX) {
|
if ((sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN ||
|
||||||
|
sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) &&
|
||||||
|
sampleRateInHz != AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
|
||||||
throw new IllegalArgumentException(sampleRateInHz
|
throw new IllegalArgumentException(sampleRateInHz
|
||||||
+ "Hz is not a supported sample rate.");
|
+ "Hz is not a supported sample rate.");
|
||||||
}
|
}
|
||||||
@@ -948,7 +948,13 @@ public class AudioTrack implements AudioRouting
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the configured audio data sample rate in Hz
|
* Returns the configured audio source sample rate in Hz.
|
||||||
|
* The initial source sample rate depends on the constructor parameters,
|
||||||
|
* but the source sample rate may change if {@link #setPlaybackRate(int)} is called.
|
||||||
|
* If the constructor had a specific sample rate, then the initial sink sample rate is that
|
||||||
|
* value.
|
||||||
|
* If the constructor had {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED},
|
||||||
|
* then the initial sink sample rate is a route-dependent default value based on the source [sic].
|
||||||
*/
|
*/
|
||||||
public int getSampleRate() {
|
public int getSampleRate() {
|
||||||
return mSampleRate;
|
return mSampleRate;
|
||||||
@@ -1218,6 +1224,7 @@ public class AudioTrack implements AudioRouting
|
|||||||
* to a higher value than the initial source sample rate, be sure to configure the buffer size
|
* to a higher value than the initial source sample rate, be sure to configure the buffer size
|
||||||
* based on the highest planned sample rate.
|
* based on the highest planned sample rate.
|
||||||
* @param sampleRateInHz the source sample rate expressed in Hz.
|
* @param sampleRateInHz the source sample rate expressed in Hz.
|
||||||
|
* {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} is not permitted.
|
||||||
* @param channelConfig describes the configuration of the audio channels.
|
* @param channelConfig describes the configuration of the audio channels.
|
||||||
* See {@link AudioFormat#CHANNEL_OUT_MONO} and
|
* See {@link AudioFormat#CHANNEL_OUT_MONO} and
|
||||||
* {@link AudioFormat#CHANNEL_OUT_STEREO}
|
* {@link AudioFormat#CHANNEL_OUT_STEREO}
|
||||||
@@ -1255,7 +1262,9 @@ public class AudioTrack implements AudioRouting
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sample rate, note these values are subject to change
|
// sample rate, note these values are subject to change
|
||||||
if ( (sampleRateInHz < SAMPLE_RATE_HZ_MIN) || (sampleRateInHz > SAMPLE_RATE_HZ_MAX) ) {
|
// Note: AudioFormat.SAMPLE_RATE_UNSPECIFIED is not allowed
|
||||||
|
if ( (sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN) ||
|
||||||
|
(sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) ) {
|
||||||
loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate.");
|
loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate.");
|
||||||
return ERROR_BAD_VALUE;
|
return ERROR_BAD_VALUE;
|
||||||
}
|
}
|
||||||
@@ -2763,7 +2772,7 @@ public class AudioTrack implements AudioRouting
|
|||||||
// AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC
|
// AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC
|
||||||
private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this,
|
private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this,
|
||||||
Object /*AudioAttributes*/ attributes,
|
Object /*AudioAttributes*/ attributes,
|
||||||
int sampleRate, int channelMask, int channelIndexMask, int audioFormat,
|
int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
|
||||||
int buffSizeInBytes, int mode, int[] sessionId);
|
int buffSizeInBytes, int mode, int[] sessionId);
|
||||||
|
|
||||||
private native final void native_finalize();
|
private native final void native_finalize();
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ public class AudioMix {
|
|||||||
mRouteFlags = ROUTE_FLAG_RENDER;
|
mRouteFlags = ROUTE_FLAG_RENDER;
|
||||||
}
|
}
|
||||||
if (mFormat == null) {
|
if (mFormat == null) {
|
||||||
|
// FIXME Can we eliminate this? Will AudioMix work with an unspecified sample rate?
|
||||||
int rate = AudioSystem.getPrimaryOutputSamplingRate();
|
int rate = AudioSystem.getPrimaryOutputSamplingRate();
|
||||||
if (rate <= 0) {
|
if (rate <= 0) {
|
||||||
rate = 44100;
|
rate = 44100;
|
||||||
|
|||||||
Reference in New Issue
Block a user