Merge "Add audio level monitoring capabilities in Visualizer effect" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
e9b0dd899a
@@ -93,6 +93,24 @@ public class Visualizer {
|
|||||||
*/
|
*/
|
||||||
public static final int SCALING_MODE_AS_PLAYED = 1;
|
public static final int SCALING_MODE_AS_PLAYED = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* Defines a measurement mode with no requested measurement.
|
||||||
|
*/
|
||||||
|
public static final int MEASUREMENT_MODE_NONE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* Defines a measurement mode which computes the peak and RMS value in mB, where 0mB is the
|
||||||
|
* maximum sample value, and -9600mB is the minimum value.
|
||||||
|
* Values for peak and RMS can be retrieved with {@link #getIntMeasurements(int, int[])}, where
|
||||||
|
* the array holds the peak value at index {@link #MEASUREMENT_INDEX_PEAK} in the measurement
|
||||||
|
* array, and the RMS value at index {@link #MEASUREMENT_INDEX_RMS}.
|
||||||
|
*/
|
||||||
|
public static final int MEASUREMENT_MODE_PEAK_RMS = 1 << 0;
|
||||||
|
|
||||||
// to keep in sync with frameworks/base/media/jni/audioeffect/android_media_Visualizer.cpp
|
// to keep in sync with frameworks/base/media/jni/audioeffect/android_media_Visualizer.cpp
|
||||||
private static final int NATIVE_EVENT_PCM_CAPTURE = 0;
|
private static final int NATIVE_EVENT_PCM_CAPTURE = 0;
|
||||||
private static final int NATIVE_EVENT_FFT_CAPTURE = 1;
|
private static final int NATIVE_EVENT_FFT_CAPTURE = 1;
|
||||||
@@ -349,6 +367,47 @@ public class Visualizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* Sets the combination of measurement modes to be performed by this audio effect.
|
||||||
|
* @param mode a mask of the measurements to perform. The valid values are
|
||||||
|
* {@link #MEASUREMENT_MODE_NONE} (to cancel any measurement)
|
||||||
|
* or {@link #MEASUREMENT_MODE_PEAK_RMS}.
|
||||||
|
* @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE} in case of failure.
|
||||||
|
* @throws IllegalStateException
|
||||||
|
*/
|
||||||
|
public int setMeasurementMode(int mode)
|
||||||
|
throws IllegalStateException {
|
||||||
|
synchronized (mStateLock) {
|
||||||
|
if (mState == STATE_UNINITIALIZED) {
|
||||||
|
throw(new IllegalStateException("setMeasurementMode() called in wrong state: "
|
||||||
|
+ mState));
|
||||||
|
}
|
||||||
|
return native_setMeasurementMode(mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* Returns the current measurement modes performed by this audio effect
|
||||||
|
* @return the mask of the measurements,
|
||||||
|
* {@link #MEASUREMENT_MODE_NONE} (when no measurements are performed)
|
||||||
|
* or {@link #MEASUREMENT_MODE_PEAK_RMS}.
|
||||||
|
* @throws IllegalStateException
|
||||||
|
*/
|
||||||
|
public int getMeasurementMode()
|
||||||
|
throws IllegalStateException {
|
||||||
|
synchronized (mStateLock) {
|
||||||
|
if (mState == STATE_UNINITIALIZED) {
|
||||||
|
throw(new IllegalStateException("getMeasurementMode() called in wrong state: "
|
||||||
|
+ mState));
|
||||||
|
}
|
||||||
|
return native_getMeasurementMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sampling rate of the captured audio.
|
* Returns the sampling rate of the captured audio.
|
||||||
* @return the sampling rate in milliHertz.
|
* @return the sampling rate in milliHertz.
|
||||||
@@ -437,6 +496,51 @@ public class Visualizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* A class to store peak and RMS values.
|
||||||
|
* Peak and RMS are expressed in mB, as described in the
|
||||||
|
* {@link Visualizer#MEASUREMENT_MODE_PEAK_RMS} measurement mode.
|
||||||
|
*/
|
||||||
|
public static final class MeasurementPeakRms {
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
*/
|
||||||
|
public int mPeak;
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
*/
|
||||||
|
public int mRms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* Retrieves the latest peak and RMS measurement.
|
||||||
|
* Sets the peak and RMS fields of the {@link Visualizer.MeasurementPeakRms} to the latest
|
||||||
|
* measured values.
|
||||||
|
* @param measurement a non-null {@link Visualizer.MeasurementPeakRms} instance to store
|
||||||
|
* the measurement values.
|
||||||
|
* @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE},
|
||||||
|
* {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
|
||||||
|
* in case of failure.
|
||||||
|
*/
|
||||||
|
public int getMeasurementPeakRms(MeasurementPeakRms measurement) {
|
||||||
|
if (measurement == null) {
|
||||||
|
Log.e(TAG, "Cannot store measurements in a null object");
|
||||||
|
return ERROR_BAD_VALUE;
|
||||||
|
}
|
||||||
|
synchronized (mStateLock) {
|
||||||
|
if (mState != STATE_ENABLED) {
|
||||||
|
throw (new IllegalStateException("getMeasurementPeakRms() called in wrong state: "
|
||||||
|
+ mState));
|
||||||
|
}
|
||||||
|
return native_getPeakRms(measurement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Interface definitions
|
// Interface definitions
|
||||||
//--------------------
|
//--------------------
|
||||||
@@ -640,12 +744,18 @@ public class Visualizer {
|
|||||||
|
|
||||||
private native final int native_getScalingMode();
|
private native final int native_getScalingMode();
|
||||||
|
|
||||||
|
private native final int native_setMeasurementMode(int mode);
|
||||||
|
|
||||||
|
private native final int native_getMeasurementMode();
|
||||||
|
|
||||||
private native final int native_getSamplingRate();
|
private native final int native_getSamplingRate();
|
||||||
|
|
||||||
private native final int native_getWaveForm(byte[] waveform);
|
private native final int native_getWaveForm(byte[] waveform);
|
||||||
|
|
||||||
private native final int native_getFft(byte[] fft);
|
private native final int native_getFft(byte[] fft);
|
||||||
|
|
||||||
|
private native final int native_getPeakRms(MeasurementPeakRms measurement);
|
||||||
|
|
||||||
private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft);
|
private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft);
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ using namespace android;
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
static const char* const kClassPathName = "android/media/audiofx/Visualizer";
|
static const char* const kClassPathName = "android/media/audiofx/Visualizer";
|
||||||
|
static const char* const kClassPeakRmsPathName =
|
||||||
|
"android/media/audiofx/Visualizer$MeasurementPeakRms";
|
||||||
|
|
||||||
struct fields_t {
|
struct fields_t {
|
||||||
// these fields provide access from C++ to the...
|
// these fields provide access from C++ to the...
|
||||||
@@ -50,6 +52,8 @@ struct fields_t {
|
|||||||
jmethodID midPostNativeEvent; // event post callback method
|
jmethodID midPostNativeEvent; // event post callback method
|
||||||
jfieldID fidNativeVisualizer; // stores in Java the native Visualizer object
|
jfieldID fidNativeVisualizer; // stores in Java the native Visualizer object
|
||||||
jfieldID fidJniData; // stores in Java additional resources used by the native Visualizer
|
jfieldID fidJniData; // stores in Java additional resources used by the native Visualizer
|
||||||
|
jfieldID fidPeak; // to access Visualizer.MeasurementPeakRms.mPeak
|
||||||
|
jfieldID fidRms; // to access Visualizer.MeasurementPeakRms.mRms
|
||||||
};
|
};
|
||||||
static fields_t fields;
|
static fields_t fields;
|
||||||
|
|
||||||
@@ -257,6 +261,14 @@ android_media_visualizer_native_init(JNIEnv *env)
|
|||||||
|
|
||||||
fields.clazzEffect = (jclass)env->NewGlobalRef(clazz);
|
fields.clazzEffect = (jclass)env->NewGlobalRef(clazz);
|
||||||
|
|
||||||
|
// Get the Visualizer.MeasurementPeakRms class
|
||||||
|
clazz = env->FindClass(kClassPeakRmsPathName);
|
||||||
|
if (clazz == NULL) {
|
||||||
|
ALOGE("Can't find %s", kClassPeakRmsPathName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
jclass clazzMeasurementPeakRms = (jclass)env->NewGlobalRef(clazz);
|
||||||
|
|
||||||
// Get the postEvent method
|
// Get the postEvent method
|
||||||
fields.midPostNativeEvent = env->GetStaticMethodID(
|
fields.midPostNativeEvent = env->GetStaticMethodID(
|
||||||
fields.clazzEffect,
|
fields.clazzEffect,
|
||||||
@@ -283,7 +295,24 @@ android_media_visualizer_native_init(JNIEnv *env)
|
|||||||
ALOGE("Can't find Visualizer.%s", "mJniData");
|
ALOGE("Can't find Visualizer.%s", "mJniData");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// fidPeak
|
||||||
|
fields.fidPeak = env->GetFieldID(
|
||||||
|
clazzMeasurementPeakRms,
|
||||||
|
"mPeak", "I");
|
||||||
|
if (fields.fidPeak == NULL) {
|
||||||
|
ALOGE("Can't find Visualizer.MeasurementPeakRms.%s", "mPeak");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// fidRms
|
||||||
|
fields.fidRms = env->GetFieldID(
|
||||||
|
clazzMeasurementPeakRms,
|
||||||
|
"mRms", "I");
|
||||||
|
if (fields.fidRms == NULL) {
|
||||||
|
ALOGE("Can't find Visualizer.MeasurementPeakRms.%s", "mPeak");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->DeleteGlobalRef(clazzMeasurementPeakRms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_media_visualizer_effect_callback(int32_t event,
|
static void android_media_visualizer_effect_callback(int32_t event,
|
||||||
@@ -512,6 +541,26 @@ android_media_visualizer_native_getScalingMode(JNIEnv *env, jobject thiz)
|
|||||||
return lpVisualizer->getScalingMode();
|
return lpVisualizer->getScalingMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static jint
|
||||||
|
android_media_visualizer_native_setMeasurementMode(JNIEnv *env, jobject thiz, jint mode)
|
||||||
|
{
|
||||||
|
Visualizer* lpVisualizer = getVisualizer(env, thiz);
|
||||||
|
if (lpVisualizer == NULL) {
|
||||||
|
return VISUALIZER_ERROR_NO_INIT;
|
||||||
|
}
|
||||||
|
return translateError(lpVisualizer->setMeasurementMode(mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static jint
|
||||||
|
android_media_visualizer_native_getMeasurementMode(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
|
Visualizer* lpVisualizer = getVisualizer(env, thiz);
|
||||||
|
if (lpVisualizer == NULL) {
|
||||||
|
return MEASUREMENT_MODE_NONE;
|
||||||
|
}
|
||||||
|
return lpVisualizer->getMeasurementMode();
|
||||||
|
}
|
||||||
|
|
||||||
static jint
|
static jint
|
||||||
android_media_visualizer_native_getSamplingRate(JNIEnv *env, jobject thiz)
|
android_media_visualizer_native_getSamplingRate(JNIEnv *env, jobject thiz)
|
||||||
{
|
{
|
||||||
@@ -559,6 +608,25 @@ android_media_visualizer_native_getFft(JNIEnv *env, jobject thiz, jbyteArray jFf
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static jint
|
||||||
|
android_media_visualizer_native_getPeakRms(JNIEnv *env, jobject thiz, jobject jPeakRmsObj)
|
||||||
|
{
|
||||||
|
Visualizer* lpVisualizer = getVisualizer(env, thiz);
|
||||||
|
if (lpVisualizer == NULL) {
|
||||||
|
return VISUALIZER_ERROR_NO_INIT;
|
||||||
|
}
|
||||||
|
int32_t measurements[2];
|
||||||
|
jint status = translateError(
|
||||||
|
lpVisualizer->getIntMeasurements(MEASUREMENT_MODE_PEAK_RMS,
|
||||||
|
2, measurements));
|
||||||
|
if (status == VISUALIZER_SUCCESS) {
|
||||||
|
// measurement worked, write the values to the java object
|
||||||
|
env->SetIntField(jPeakRmsObj, fields.fidPeak, measurements[MEASUREMENT_IDX_PEAK]);
|
||||||
|
env->SetIntField(jPeakRmsObj, fields.fidRms, measurements[MEASUREMENT_IDX_RMS]);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static jint
|
static jint
|
||||||
android_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean jWaveform, jboolean jFft)
|
android_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean jWaveform, jboolean jFft)
|
||||||
{
|
{
|
||||||
@@ -606,9 +674,13 @@ static JNINativeMethod gMethods[] = {
|
|||||||
{"native_getCaptureSize", "()I", (void *)android_media_visualizer_native_getCaptureSize},
|
{"native_getCaptureSize", "()I", (void *)android_media_visualizer_native_getCaptureSize},
|
||||||
{"native_setScalingMode", "(I)I", (void *)android_media_visualizer_native_setScalingMode},
|
{"native_setScalingMode", "(I)I", (void *)android_media_visualizer_native_setScalingMode},
|
||||||
{"native_getScalingMode", "()I", (void *)android_media_visualizer_native_getScalingMode},
|
{"native_getScalingMode", "()I", (void *)android_media_visualizer_native_getScalingMode},
|
||||||
|
{"native_setMeasurementMode","(I)I", (void *)android_media_visualizer_native_setMeasurementMode},
|
||||||
|
{"native_getMeasurementMode","()I", (void *)android_media_visualizer_native_getMeasurementMode},
|
||||||
{"native_getSamplingRate", "()I", (void *)android_media_visualizer_native_getSamplingRate},
|
{"native_getSamplingRate", "()I", (void *)android_media_visualizer_native_getSamplingRate},
|
||||||
{"native_getWaveForm", "([B)I", (void *)android_media_visualizer_native_getWaveForm},
|
{"native_getWaveForm", "([B)I", (void *)android_media_visualizer_native_getWaveForm},
|
||||||
{"native_getFft", "([B)I", (void *)android_media_visualizer_native_getFft},
|
{"native_getFft", "([B)I", (void *)android_media_visualizer_native_getFft},
|
||||||
|
{"native_getPeakRms", "(Landroid/media/audiofx/Visualizer$MeasurementPeakRms;)I",
|
||||||
|
(void *)android_media_visualizer_native_getPeakRms},
|
||||||
{"native_setPeriodicCapture","(IZZ)I",(void *)android_media_setPeriodicCapture},
|
{"native_setPeriodicCapture","(IZZ)I",(void *)android_media_setPeriodicCapture},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user