VolumeShaper: Update Builder methods and Object overrides
Builder methods now throw IllegalArgumentExceptions on invalid conditions. Object hashCode, toString, equals updated for element-wise structural equivalence. Test: CTS VolumeShaperTest Bug: 31015569 Change-Id: I02860a51da58d8207145a9b8a5d2cb13806774b4
This commit is contained in:
@@ -25,6 +25,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.AutoCloseable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -115,6 +116,7 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
* @param configuration
|
||||
* @param operation
|
||||
* @return id a non-negative shaper id.
|
||||
* @throws IllegalStateException if the player has been deallocated or is uninitialized.
|
||||
*/
|
||||
private int applyPlayer(
|
||||
@NonNull VolumeShaper.Configuration configuration,
|
||||
@@ -147,6 +149,7 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
* Internal call to retrieve the current VolumeShaper state.
|
||||
* @param id
|
||||
* @return the current {@vode VolumeShaper.State}
|
||||
* @throws IllegalStateException if the player has been deallocated or is uninitialized.
|
||||
*/
|
||||
private @NonNull VolumeShaper.State getStatePlayer(int id) {
|
||||
final VolumeShaper.State state;
|
||||
@@ -172,10 +175,10 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
* <p>
|
||||
* A {@code VolumeShaper.Configuration} is used by
|
||||
* {@link VolumeAutomation#createVolumeShaper(Configuration)
|
||||
* VolumeAutomation#createVolumeShaper(Configuration)} to create
|
||||
* VolumeAutomation.createVolumeShaper(Configuration)} to create
|
||||
* a {@code VolumeShaper} and
|
||||
* by {@link VolumeShaper#replace(Configuration, Operation, boolean)
|
||||
* VolumeShaper#replace(Configuration, Operation, boolean)}
|
||||
* VolumeShaper.replace(Configuration, Operation, boolean)}
|
||||
* to replace an existing {@code configuration}.
|
||||
*/
|
||||
public static final class Configuration implements Parcelable {
|
||||
@@ -365,31 +368,34 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
private final int mId;
|
||||
|
||||
// valid when mType is TYPE_SCALE
|
||||
private final int mInterpolatorType;
|
||||
private final int mOptionFlags;
|
||||
private final double mDurationMs;
|
||||
private final int mInterpolatorType;
|
||||
private final float[] mTimes;
|
||||
private final float[] mVolumes;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VolumeShaper.Configuration["
|
||||
+ "mType=" + mType
|
||||
return "VolumeShaper.Configuration{"
|
||||
+ "mType = " + mType
|
||||
+ ", mId = " + mId
|
||||
+ (mType == TYPE_ID
|
||||
? ",mId" + mId
|
||||
: ",mInterpolatorType=" + mInterpolatorType
|
||||
+ ",mOptionFlags=" + mOptionFlags
|
||||
+ ",mDurationMs=" + mDurationMs
|
||||
+ ",mTimes[]=" + mTimes
|
||||
+ ",mVolumes[]=" + mVolumes
|
||||
+ "]");
|
||||
? "}"
|
||||
: ", mOptionFlags = 0x" + Integer.toHexString(mOptionFlags).toUpperCase()
|
||||
+ ", mDurationMs = " + mDurationMs
|
||||
+ ", mInterpolatorType = " + mInterpolatorType
|
||||
+ ", mTimes[] = " + Arrays.toString(mTimes)
|
||||
+ ", mVolumes[] = " + Arrays.toString(mVolumes)
|
||||
+ "}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mType == TYPE_ID
|
||||
? Objects.hash(mType, mId)
|
||||
: Objects.hash(mType, mInterpolatorType, mDurationMs, mTimes, mVolumes);
|
||||
: Objects.hash(mType, mId,
|
||||
mOptionFlags, mDurationMs, mInterpolatorType,
|
||||
Arrays.hashCode(mTimes), Arrays.hashCode(mVolumes));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -397,12 +403,17 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
if (!(o instanceof Configuration)) return false;
|
||||
if (o == this) return true;
|
||||
final Configuration other = (Configuration) o;
|
||||
return mType == other.mType &&
|
||||
(mType == TYPE_ID ? mId == other.mId
|
||||
: mInterpolatorType == other.mInterpolatorType
|
||||
&& mDurationMs == other.mDurationMs
|
||||
&& mTimes == other.mTimes
|
||||
&& mVolumes == other.mVolumes);
|
||||
// Note that exact floating point equality may not be guaranteed
|
||||
// for a theoretically idempotent operation; for example,
|
||||
// there are many cases where a + b - b != a.
|
||||
return mType == other.mType
|
||||
&& mId == other.mId
|
||||
&& (mType == TYPE_ID
|
||||
|| (mOptionFlags == other.mOptionFlags
|
||||
&& mDurationMs == other.mDurationMs
|
||||
&& mInterpolatorType == other.mInterpolatorType
|
||||
&& Arrays.equals(mTimes, other.mTimes)
|
||||
&& Arrays.equals(mVolumes, other.mVolumes)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -412,14 +423,22 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
// this needs to match the native VolumeShaper.Configuration parceling
|
||||
dest.writeInt(mType);
|
||||
dest.writeInt(mId);
|
||||
if (mType != TYPE_ID) {
|
||||
dest.writeInt(mInterpolatorType);
|
||||
dest.writeInt(mOptionFlags);
|
||||
dest.writeDouble(mDurationMs);
|
||||
dest.writeFloatArray(mTimes);
|
||||
dest.writeFloatArray(mVolumes);
|
||||
// this needs to match the native Interpolator parceling
|
||||
dest.writeInt(mInterpolatorType);
|
||||
dest.writeFloat(0.f); // first slope
|
||||
dest.writeFloat(0.f); // last slope
|
||||
// mTimes and mVolumes should have the same length.
|
||||
dest.writeInt(mTimes.length);
|
||||
for (int i = 0; i < mTimes.length; ++i) {
|
||||
dest.writeFloat(mTimes[i]);
|
||||
dest.writeFloat(mVolumes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,19 +446,34 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
= new Parcelable.Creator<VolumeShaper.Configuration>() {
|
||||
@Override
|
||||
public VolumeShaper.Configuration createFromParcel(Parcel p) {
|
||||
// this needs to match the native VolumeShaper.Configuration parceling
|
||||
final int type = p.readInt();
|
||||
final int id = p.readInt();
|
||||
if (type == TYPE_ID) {
|
||||
return new VolumeShaper.Configuration(id);
|
||||
} else {
|
||||
final int optionFlags = p.readInt();
|
||||
final double durationMs = p.readDouble();
|
||||
// this needs to match the native Interpolator parceling
|
||||
final int interpolatorType = p.readInt();
|
||||
final float firstSlope = p.readFloat(); // ignored
|
||||
final float lastSlope = p.readFloat(); // ignored
|
||||
final int length = p.readInt();
|
||||
final float[] times = new float[length];
|
||||
final float[] volumes = new float[length];
|
||||
for (int i = 0; i < length; ++i) {
|
||||
times[i] = p.readFloat();
|
||||
volumes[i] = p.readFloat();
|
||||
}
|
||||
|
||||
return new VolumeShaper.Configuration(
|
||||
type,
|
||||
id, // id
|
||||
p.readInt(), // interpolatorType
|
||||
p.readInt(), // optionFlags
|
||||
p.readDouble(), // durationMs
|
||||
p.createFloatArray(), // times
|
||||
p.createFloatArray()); // volumes
|
||||
id,
|
||||
optionFlags,
|
||||
durationMs,
|
||||
interpolatorType,
|
||||
times,
|
||||
volumes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,16 +516,16 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
*/
|
||||
private Configuration(@Type int type,
|
||||
int id,
|
||||
@InterpolatorType int interpolatorType,
|
||||
@OptionFlag int optionFlags,
|
||||
double durationMs,
|
||||
@InterpolatorType int interpolatorType,
|
||||
@NonNull float[] times,
|
||||
@NonNull float[] volumes) {
|
||||
mType = type;
|
||||
mId = id;
|
||||
mInterpolatorType = interpolatorType;
|
||||
mOptionFlags = optionFlags;
|
||||
mDurationMs = durationMs;
|
||||
mInterpolatorType = interpolatorType;
|
||||
// Builder should have cloned these arrays already.
|
||||
mTimes = times;
|
||||
mVolumes = volumes;
|
||||
@@ -568,8 +602,12 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
* @return null if no error, or the reason in a {@code String} for an error.
|
||||
*/
|
||||
private static @Nullable String checkCurveForErrors(
|
||||
@NonNull float[] times, @NonNull float[] volumes, boolean log) {
|
||||
if (times.length != volumes.length) {
|
||||
@Nullable float[] times, @Nullable float[] volumes, boolean log) {
|
||||
if (times == null) {
|
||||
return "times array must be non-null";
|
||||
} else if (volumes == null) {
|
||||
return "volumes array must be non-null";
|
||||
} else if (times.length != volumes.length) {
|
||||
return "array length must match";
|
||||
} else if (times.length < 2) {
|
||||
return "array length must be at least 2";
|
||||
@@ -605,7 +643,15 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
return null; // no errors
|
||||
}
|
||||
|
||||
private static void checkValidVolume(float volume, boolean log) {
|
||||
private static void checkCurveForErrorsAndThrowException(
|
||||
@Nullable float[] times, @Nullable float[] volumes, boolean log) {
|
||||
final String error = checkCurveForErrors(times, volumes, log);
|
||||
if (error != null) {
|
||||
throw new IllegalArgumentException(error);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkValidVolumeAndThrowException(float volume, boolean log) {
|
||||
if (log) {
|
||||
if (!(volume <= 0.f) /* handle nan */) {
|
||||
throw new IllegalArgumentException("dbfs volume must be 0.f or less");
|
||||
@@ -678,17 +724,22 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
mOptionFlags = configuration.getAllOptionFlags();
|
||||
mInterpolatorType = configuration.getInterpolatorType();
|
||||
mDurationMs = configuration.getDurationMs();
|
||||
mTimes = configuration.getTimes();
|
||||
mVolumes = configuration.getVolumes();
|
||||
mTimes = configuration.getTimes().clone();
|
||||
mVolumes = configuration.getVolumes().clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Set the id for system defined shapers.
|
||||
* @param id
|
||||
* @return
|
||||
* Set the {@code id} for system defined shapers.
|
||||
* @param id the {@code id} to set. If non-negative, then it is used.
|
||||
* If -1, then the system is expected to assign one.
|
||||
* @return the same {@code Builder} instance.
|
||||
* @throws IllegalArgumentException if {@code id} < -1.
|
||||
*/
|
||||
public @NonNull Builder setId(int id) {
|
||||
if (id < -1) {
|
||||
throw new IllegalArgumentException("invalid id: " + id);
|
||||
}
|
||||
mId = id;
|
||||
return this;
|
||||
}
|
||||
@@ -789,11 +840,8 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
*/
|
||||
|
||||
public @NonNull Builder setCurve(@NonNull float[] times, @NonNull float[] volumes) {
|
||||
String error = checkCurveForErrors(
|
||||
checkCurveForErrorsAndThrowException(
|
||||
times, volumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
|
||||
if (error != null) {
|
||||
throw new IllegalArgumentException(error);
|
||||
}
|
||||
mTimes = times.clone();
|
||||
mVolumes = volumes.clone();
|
||||
return this;
|
||||
@@ -805,13 +853,19 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
* to the start.
|
||||
*
|
||||
* @return the same {@code Builder} instance.
|
||||
* @throws IllegalArgumentException if curve has not been set.
|
||||
*/
|
||||
public @NonNull Builder reflectTimes() {
|
||||
checkCurveForErrorsAndThrowException(
|
||||
mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
|
||||
int i;
|
||||
for (i = 0; i < mTimes.length / 2; ++i) {
|
||||
float temp = mTimes[0];
|
||||
float temp = mTimes[i];
|
||||
mTimes[i] = 1.f - mTimes[mTimes.length - 1 - i];
|
||||
mTimes[mTimes.length - 1 - i] = 1.f - temp;
|
||||
temp = mVolumes[i];
|
||||
mVolumes[i] = mVolumes[mVolumes.length - 1 - i];
|
||||
mVolumes[mVolumes.length - 1 - i] = temp;
|
||||
}
|
||||
if ((mTimes.length & 1) != 0) {
|
||||
mTimes[i] = 1.f - mTimes[i];
|
||||
@@ -824,23 +878,24 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
* becomes the min volume and vice versa.
|
||||
*
|
||||
* @return the same {@code Builder} instance.
|
||||
* @throws IllegalArgumentException if curve has not been set.
|
||||
*/
|
||||
public @NonNull Builder invertVolumes() {
|
||||
if (mVolumes.length >= 2) {
|
||||
float min = mVolumes[0];
|
||||
float max = mVolumes[0];
|
||||
for (int i = 1; i < mVolumes.length; ++i) {
|
||||
if (mVolumes[i] < min) {
|
||||
min = mVolumes[i];
|
||||
} else if (mVolumes[i] > max) {
|
||||
max = mVolumes[i];
|
||||
}
|
||||
checkCurveForErrorsAndThrowException(
|
||||
mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
|
||||
float min = mVolumes[0];
|
||||
float max = mVolumes[0];
|
||||
for (int i = 1; i < mVolumes.length; ++i) {
|
||||
if (mVolumes[i] < min) {
|
||||
min = mVolumes[i];
|
||||
} else if (mVolumes[i] > max) {
|
||||
max = mVolumes[i];
|
||||
}
|
||||
}
|
||||
|
||||
final float maxmin = max + min;
|
||||
for (int i = 0; i < mVolumes.length; ++i) {
|
||||
mVolumes[i] = maxmin - mVolumes[i];
|
||||
}
|
||||
final float maxmin = max + min;
|
||||
for (int i = 0; i < mVolumes.length; ++i) {
|
||||
mVolumes[i] = maxmin - mVolumes[i];
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -853,11 +908,13 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
*
|
||||
* @param volume the target end volume to use.
|
||||
* @return the same {@code Builder} instance.
|
||||
* @throws IllegalArgumentException if {@code volume} is not valid.
|
||||
* @throws IllegalArgumentException if {@code volume}
|
||||
* is not valid or if curve has not been set.
|
||||
*/
|
||||
public @NonNull Builder scaleToEndVolume(float volume) {
|
||||
final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
|
||||
checkValidVolume(volume, log);
|
||||
checkCurveForErrorsAndThrowException(mTimes, mVolumes, log);
|
||||
checkValidVolumeAndThrowException(volume, log);
|
||||
final float startVolume = mVolumes[0];
|
||||
final float endVolume = mVolumes[mVolumes.length - 1];
|
||||
if (endVolume == startVolume) {
|
||||
@@ -885,11 +942,13 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
*
|
||||
* @param volume the target start volume to use.
|
||||
* @return the same {@code Builder} instance.
|
||||
* @throws IllegalArgumentException if {@code volume} is not valid.
|
||||
* @throws IllegalArgumentException if {@code volume}
|
||||
* is not valid or if curve has not been set.
|
||||
*/
|
||||
public @NonNull Builder scaleToStartVolume(float volume) {
|
||||
final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
|
||||
checkValidVolume(volume, log);
|
||||
checkCurveForErrorsAndThrowException(mTimes, mVolumes, log);
|
||||
checkValidVolumeAndThrowException(volume, log);
|
||||
final float startVolume = mVolumes[0];
|
||||
final float endVolume = mVolumes[mVolumes.length - 1];
|
||||
if (endVolume == startVolume) {
|
||||
@@ -911,16 +970,14 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
/**
|
||||
* Builds a new {@link VolumeShaper} object.
|
||||
*
|
||||
* @return a new {@link VolumeShaper} object
|
||||
* @return a new {@link VolumeShaper} object.
|
||||
* @throws IllegalArgumentException if curve is not properly set.
|
||||
*/
|
||||
public @NonNull Configuration build() {
|
||||
String error = checkCurveForErrors(
|
||||
checkCurveForErrorsAndThrowException(
|
||||
mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
|
||||
if (error != null) {
|
||||
throw new IllegalArgumentException(error);
|
||||
}
|
||||
return new Configuration(mType, mId, mInterpolatorType, mOptionFlags,
|
||||
mDurationMs, mTimes, mVolumes);
|
||||
return new Configuration(mType, mId, mOptionFlags, mDurationMs,
|
||||
mInterpolatorType, mTimes, mVolumes);
|
||||
}
|
||||
} // Configuration.Builder
|
||||
} // Configuration
|
||||
@@ -1011,10 +1068,10 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VolumeShaper.Operation["
|
||||
+ "mFlags=" + mFlags
|
||||
+ ",mReplaceId" + mReplaceId
|
||||
+ "]";
|
||||
return "VolumeShaper.Operation{"
|
||||
+ "mFlags = 0x" + Integer.toHexString(mFlags).toUpperCase()
|
||||
+ ", mReplaceId = " + mReplaceId
|
||||
+ "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1027,6 +1084,8 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
if (!(o instanceof Operation)) return false;
|
||||
if (o == this) return true;
|
||||
final Operation other = (Operation) o;
|
||||
// if xOffset (native field only) is brought into Java
|
||||
// we need to do proper NaN comparison as that is allowed.
|
||||
return mFlags == other.mFlags
|
||||
&& mReplaceId == other.mReplaceId;
|
||||
}
|
||||
@@ -1038,17 +1097,24 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
// this needs to match the native VolumeShaper.Operation parceling
|
||||
dest.writeInt(mFlags);
|
||||
dest.writeInt(mReplaceId);
|
||||
dest.writeFloat(Float.NaN); // xOffset (ignored at Java level)
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<VolumeShaper.Operation> CREATOR
|
||||
= new Parcelable.Creator<VolumeShaper.Operation>() {
|
||||
@Override
|
||||
public VolumeShaper.Operation createFromParcel(Parcel p) {
|
||||
// this needs to match the native VolumeShaper.Operation parceling
|
||||
final int flags = p.readInt();
|
||||
final int replaceId = p.readInt();
|
||||
final float xOffset = p.readFloat(); // ignored at Java level
|
||||
|
||||
return new VolumeShaper.Operation(
|
||||
p.readInt() // flags
|
||||
, p.readInt()); // replaceId
|
||||
flags
|
||||
, replaceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1154,6 +1220,7 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
*
|
||||
* @param flags new value for {@code flags}, consisting of ORed flags.
|
||||
* @return the same {@code Builder} instance.
|
||||
* @throws IllegalArgumentException if {@code flags} contains invalid set bits.
|
||||
*/
|
||||
private @NonNull Builder setFlags(@Flag int flags) {
|
||||
if ((flags & ~FLAG_PUBLIC_ALL) != 0) {
|
||||
@@ -1187,10 +1254,10 @@ public final class VolumeShaper implements AutoCloseable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VolumeShaper.State["
|
||||
+ "mVolume=" + mVolume
|
||||
+ ",mXOffset" + mXOffset
|
||||
+ "]";
|
||||
return "VolumeShaper.State{"
|
||||
+ "mVolume = " + mVolume
|
||||
+ ", mXOffset = " + mXOffset
|
||||
+ "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,9 +29,9 @@ struct VolumeShaperHelper {
|
||||
jmethodID coConstructId;
|
||||
jfieldID coTypeId;
|
||||
jfieldID coIdId;
|
||||
jfieldID coInterpolatorTypeId;
|
||||
jfieldID coOptionFlagsId;
|
||||
jfieldID coDurationMsId;
|
||||
jfieldID coInterpolatorTypeId;
|
||||
jfieldID coTimesId;
|
||||
jfieldID coVolumesId;
|
||||
|
||||
@@ -56,12 +56,12 @@ struct VolumeShaperHelper {
|
||||
if (coClazz == nullptr) {
|
||||
return;
|
||||
}
|
||||
coConstructId = env->GetMethodID(coClazz, "<init>", "(IIIID[F[F)V");
|
||||
coConstructId = env->GetMethodID(coClazz, "<init>", "(IIIDI[F[F)V");
|
||||
coTypeId = env->GetFieldID(coClazz, "mType", "I");
|
||||
coIdId = env->GetFieldID(coClazz, "mId", "I");
|
||||
coInterpolatorTypeId = env->GetFieldID(coClazz, "mInterpolatorType", "I");
|
||||
coOptionFlagsId = env->GetFieldID(coClazz, "mOptionFlags", "I");
|
||||
coDurationMsId = env->GetFieldID(coClazz, "mDurationMs", "D");
|
||||
coInterpolatorTypeId = env->GetFieldID(coClazz, "mInterpolatorType", "I");
|
||||
coTimesId = env->GetFieldID(coClazz, "mTimes", "[F");
|
||||
coVolumesId = env->GetFieldID(coClazz, "mVolumes", "[F");
|
||||
env->DeleteLocalRef(lclazz);
|
||||
@@ -108,14 +108,14 @@ struct VolumeShaperHelper {
|
||||
configuration->setId(
|
||||
(int)env->GetIntField(jshaper, fields.coIdId));
|
||||
if (configuration->getType() == VolumeShaper::Configuration::TYPE_SCALE) {
|
||||
configuration->setInterpolatorType(
|
||||
(VolumeShaper::Configuration::InterpolatorType)
|
||||
env->GetIntField(jshaper, fields.coInterpolatorTypeId));
|
||||
configuration->setOptionFlags(
|
||||
(VolumeShaper::Configuration::OptionFlag)
|
||||
env->GetIntField(jshaper, fields.coOptionFlagsId));
|
||||
configuration->setDurationMs(
|
||||
(double)env->GetDoubleField(jshaper, fields.coDurationMsId));
|
||||
configuration->setInterpolatorType(
|
||||
(VolumeShaper::Configuration::InterpolatorType)
|
||||
env->GetIntField(jshaper, fields.coInterpolatorTypeId));
|
||||
|
||||
// convert point arrays
|
||||
jobject xobj = env->GetObjectField(jshaper, fields.coTimesId);
|
||||
@@ -165,9 +165,9 @@ struct VolumeShaperHelper {
|
||||
jvalue args[7];
|
||||
args[0].i = (jint)configuration->getType();
|
||||
args[1].i = (jint)configuration->getId();
|
||||
args[2].i = (jint)configuration->getInterpolatorType();
|
||||
args[3].i = (jint)configuration->getOptionFlags();
|
||||
args[4].d = (jdouble)configuration->getDurationMs();
|
||||
args[2].i = (jint)configuration->getOptionFlags();
|
||||
args[3].d = (jdouble)configuration->getDurationMs();
|
||||
args[4].i = (jint)configuration->getInterpolatorType();
|
||||
args[5].l = xarray;
|
||||
args[6].l = yarray;
|
||||
jobject jshaper = env->NewObjectA(fields.coClazz, fields.coConstructId, args);
|
||||
|
||||
Reference in New Issue
Block a user