/* * Copyright (C) 2014 Haruki Hasegawa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.h6ah4i.android.media.opensl.audiofx; import android.util.Log; import com.h6ah4i.android.media.audiofx.IEnvironmentalReverb; import com.h6ah4i.android.media.opensl.OpenSLMediaPlayer; import com.h6ah4i.android.media.opensl.OpenSLMediaPlayerContext; import com.h6ah4i.android.media.opensl.OpenSLMediaPlayerNativeLibraryLoader; public class OpenSLEnvironmentalReverb extends OpenSLAudioEffect implements IEnvironmentalReverb { private static final String TAG = "EnvironmentalReverb"; private static final int AUX_EFFECT_ID = OpenSLMediaPlayer.Internal.AUX_EFFECT_ENVIRONMENTAL_REVERB; // fields private long mNativeHandle; private static final boolean HAS_NATIVE; private int[] mParamIntBuff = new int[10]; private short[] mParamShortBuff = new short[1]; private boolean[] mParamBoolBuff = new boolean[1]; static { // load native library HAS_NATIVE = OpenSLMediaPlayerNativeLibraryLoader.loadLibraries(); } public OpenSLEnvironmentalReverb(OpenSLMediaPlayerContext context) { if (context == null) throw new IllegalArgumentException("The argument 'context' cannot be null"); if (HAS_NATIVE) { mNativeHandle = createNativeImplHandle( OpenSLMediaPlayer.Internal.getNativeHandle(context)); } if (mNativeHandle == 0) { throw new UnsupportedOperationException("Failed to initialize native layer"); } } @Override protected void finalize() throws Throwable { release(); super.finalize(); } @Override public void release() { try { if (HAS_NATIVE && mNativeHandle != 0) { deleteNativeImplHandle(mNativeHandle); mNativeHandle = 0; } } catch (Exception e) { Log.e(TAG, "release()", e); } } @Override public int getId() { checkNativeImplIsAvailable(); final int[] id = mParamIntBuff; final int result = getIdImplNative(mNativeHandle, id); parseResultAndThrowExceptForIOExceptions(result); return id[0]; } @Override public int setEnabled(boolean enabled) throws IllegalStateException { checkNativeImplIsAvailable(); try { final int result = setEnabledImplNative(mNativeHandle, enabled); parseResultAndThrowExceptForIOExceptions(result); return SUCCESS; } catch (UnsupportedOperationException e) { return ERROR_INVALID_OPERATION; } } @Override public boolean getEnabled() throws IllegalStateException { checkNativeImplIsAvailable(); final boolean[] enabled = mParamBoolBuff; final int result = getEnabledImplNative(mNativeHandle, enabled); if (result == OpenSLMediaPlayer.Internal.RESULT_CONTROL_LOST) return false; parseResultAndThrowExceptForIOExceptions(result); return enabled[0]; } @Override public boolean hasControl() throws IllegalStateException { checkNativeImplIsAvailable(); final boolean[] hasControl = mParamBoolBuff; final int result = hasControlImplNative(mNativeHandle, hasControl); if (result == OpenSLMediaPlayer.Internal.RESULT_CONTROL_LOST) return false; parseResultAndThrowExceptForIOExceptions(result); return hasControl[0]; } @Override public short getDecayHFRatio() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final short[] decayHFRatio = mParamShortBuff; final int result = getDecayHFRatioImplNative(mNativeHandle, decayHFRatio); parseResultAndThrowExceptForIOExceptions(result); return decayHFRatio[0]; } @Override public int getDecayTime() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int[] decayTime = mParamIntBuff; final int result = getDecayTimeImplNative(mNativeHandle, decayTime); parseResultAndThrowExceptForIOExceptions(result); return decayTime[0]; } @Override public short getDensity() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final short[] density = mParamShortBuff; final int result = getDensityImplNative(mNativeHandle, density); parseResultAndThrowExceptForIOExceptions(result); return density[0]; } @Override public short getDiffusion() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final short[] diffusion = mParamShortBuff; final int result = getDiffusionImplNative(mNativeHandle, diffusion); parseResultAndThrowExceptForIOExceptions(result); return diffusion[0]; } @Override public IEnvironmentalReverb.Settings getProperties() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int[] values = mParamIntBuff; final int result = getPropertiesImplNative(mNativeHandle, values); parseResultAndThrowExceptForIOExceptions(result); final IEnvironmentalReverb.Settings settings = new Settings(); settings.roomLevel = (short) (values[0] & 0xffff); settings.roomHFLevel = (short) (values[1] & 0xffff); settings.decayTime = values[2]; settings.decayHFRatio = (short) (values[3] & 0xffff); settings.reflectionsLevel = (short) (values[4] & 0xffff); settings.reflectionsDelay = values[5]; settings.reverbLevel = (short) (values[6] & 0xffff); settings.reverbDelay = values[7]; settings.diffusion = (short) (values[8] & 0xffff); settings.density = (short) (values[9] & 0xffff); return settings; } @Override public int getReflectionsDelay() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int[] reflectionsDelay = mParamIntBuff; final int result = getReflectionsDelayImplNative(mNativeHandle, reflectionsDelay); parseResultAndThrowExceptForIOExceptions(result); return reflectionsDelay[0]; } @Override public short getReflectionsLevel() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final short[] reflectionsLevel = mParamShortBuff; final int result = getReflectionsLevelImplNative(mNativeHandle, reflectionsLevel); parseResultAndThrowExceptForIOExceptions(result); return reflectionsLevel[0]; } @Override public int getReverbDelay() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int[] reverbDelay = mParamIntBuff; final int result = getReverbDelayImplNative(mNativeHandle, reverbDelay); parseResultAndThrowExceptForIOExceptions(result); return reverbDelay[0]; } @Override public short getReverbLevel() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final short[] reverbLevel = mParamShortBuff; final int result = getReverbLevelImplNative(mNativeHandle, reverbLevel); parseResultAndThrowExceptForIOExceptions(result); return reverbLevel[0]; } @Override public short getRoomHFLevel() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final short[] roomHF = mParamShortBuff; final int result = getRoomHFLevelImplNative(mNativeHandle, roomHF); parseResultAndThrowExceptForIOExceptions(result); return roomHF[0]; } @Override public short getRoomLevel() throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final short[] roomLevel = mParamShortBuff; final int result = getRoomLevelImplNative(mNativeHandle, roomLevel); parseResultAndThrowExceptForIOExceptions(result); return roomLevel[0]; } @Override public void setDecayHFRatio(short decayHFRatio) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setDecayHFRatioImplNative(mNativeHandle, decayHFRatio); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setDecayTime(int decayTime) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setDecayTimeImplNative(mNativeHandle, decayTime); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setDensity(short density) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setDensityImplNative(mNativeHandle, density); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setDiffusion(short diffusion) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setDiffusionImplNative(mNativeHandle, diffusion); parseResultAndThrowExceptForIOExceptions(result); } // void setParameterListener(EnvironmentalReverb.OnParameterChangeListener // listener) { // // } @Override public void setProperties(IEnvironmentalReverb.Settings settings) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); if (settings == null) throw new IllegalArgumentException("The argument 'settings' cannot be null"); final int[] values = mParamIntBuff; values[0] = settings.roomLevel & 0xffff; values[1] = settings.roomHFLevel & 0xffff; values[2] = settings.decayTime; values[3] = settings.decayHFRatio & 0xffff; values[4] = settings.reflectionsLevel & 0xffff; values[5] = settings.reflectionsDelay; values[6] = settings.reverbLevel & 0xffff; values[7] = settings.reverbDelay; values[8] = settings.diffusion & 0xffff; values[9] = settings.density & 0xffff; final int result = setPropertiesImplNative(mNativeHandle, values); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setReflectionsDelay(int reflectionsDelay) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setReflectionsDelayImplNative(mNativeHandle, reflectionsDelay); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setReflectionsLevel(short reflectionsLevel) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setReflectionsDelayImplNative(mNativeHandle, reflectionsLevel); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setReverbDelay(int reverbDelay) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setReverbDelayImplNative(mNativeHandle, reverbDelay); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setReverbLevel(short reverbLevel) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setReverbLevelImplNative(mNativeHandle, reverbLevel); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setRoomHFLevel(short roomHF) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setRoomHFLevelImplNative(mNativeHandle, roomHF); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setRoomLevel(short room) throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException { checkNativeImplIsAvailable(); final int result = setRoomLevelImplNative(mNativeHandle, room); parseResultAndThrowExceptForIOExceptions(result); } @Override public void setParameterListener(IEnvironmentalReverb.OnParameterChangeListener listener) { // this method is not supported. } // // Utilities // private void checkNativeImplIsAvailable() throws IllegalStateException { if (mNativeHandle == 0) { throw new IllegalStateException("Native implemenation handle is not present"); } } // // Native methods // private static native long createNativeImplHandle(long context_handle); private static native void deleteNativeImplHandle(long handle); private static native int setEnabledImplNative(long handle, boolean enabled); private static native int getEnabledImplNative(long handle, boolean[] enabled); private static native int getIdImplNative(long handle, int[] id); private static native int hasControlImplNative(long handle, boolean[] hasControl); private static native int getDecayHFRatioImplNative(long handle, short[] decayHFRatio); private static native int getDecayTimeImplNative(long handle, int[] decayTime); private static native int getDensityImplNative(long handle, short[] density); private static native int getDiffusionImplNative(long handle, short[] diffusion); private static native int getPropertiesImplNative(long handle, int[] settings); private static native int getReflectionsDelayImplNative(long handle, int[] reflectionsDecay); private static native int getReflectionsLevelImplNative(long handle, short[] reflectionsLevel); private static native int getReverbDelayImplNative(long handle, int[] reverbDelay); private static native int getReverbLevelImplNative(long handle, short[] reverbLevel); private static native int getRoomHFLevelImplNative(long handle, short[] roomHF); private static native int getRoomLevelImplNative(long handle, short[] roomLevel); private static native int setDecayHFRatioImplNative(long handle, short decayHFRatio); private static native int setDecayTimeImplNative(long handle, int decayTime); private static native int setDensityImplNative(long handle, short density); private static native int setDiffusionImplNative(long handle, short diffusion); // private static native int setParameterListenerImplNative(long handle, // EnvironmentalReverb.OnParameterChangeListener listener); private static native int setPropertiesImplNative(long handle, int[] settings); private static native int setReflectionsDelayImplNative(long handle, int reflectionsDelay); private static native int setReflectionsLevelImplNative(long handle, short reflectionsLevel); private static native int setReverbDelayImplNative(long handle, int reverbDelay); private static native int setReverbLevelImplNative(long handle, short reverbLevel); private static native int setRoomHFLevelImplNative(long handle, short roomHF); private static native int setRoomLevelImplNative(long handle, short room); private static native int usePresetImplNative(long handle, int preset); }