/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * 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.android.mediaframeworktest.functional;

import com.android.mediaframeworktest.MediaFrameworkTest;
import com.android.mediaframeworktest.MediaNames;
import android.content.res.AssetFileDescriptor;
import android.media.audiofx.AudioEffect;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.audiofx.EnvironmentalReverb;
import android.media.audiofx.Equalizer;
import android.media.MediaPlayer;

import android.os.Looper;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;

import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.util.UUID;

/**
 * Junit / Instrumentation test case for the media AudioTrack api

 */
public class MediaAudioEffectTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
    private String TAG = "MediaAudioEffectTest";

    private AudioEffect mEffect = null;
    private boolean mHasControl = false;
    private boolean mIsEnabled = false;
    private int mParameterChanged = -1;
    private MediaPlayer mMediaPlayer = null;
    private boolean mInitialized = false;
    private Looper mLooper = null;
    private int mError = 0;
    private final Object lock = new Object();

    public MediaAudioEffectTest() {
        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
    }

    @Override
    protected void setUp() throws Exception {
      super.setUp();
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
    }

    private static void assumeTrue(String message, boolean cond) {
        assertTrue("(assume)"+message, cond);
    }

    private void log(String testName, String message) {
        Log.v(TAG, "["+testName+"] "+message);
    }

    private void loge(String testName, String message) {
        Log.e(TAG, "["+testName+"] "+message);
    }

    //-----------------------------------------------------------------
    // AUDIOEFFECT TESTS:
    //----------------------------------

    //-----------------------------------------------------------------
    // 0 - static methods
    //----------------------------------

    //Test case 0.0: test queryEffects() and available effects
    @LargeTest
    public void test0_0QueryEffects() throws Exception {

        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();

        assertTrue("test0_0QueryEffects: number of effects < 4: "+desc.length, (desc.length >= 4));

        boolean hasEQ = false;
        boolean hasBassBoost = false;
        boolean hasVirtualizer = false;
        boolean hasEnvReverb = false;

        for (int i = 0; i < desc.length; i++) {
            if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_EQUALIZER)) {
                hasEQ = true;
            } if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_BASS_BOOST)) {
                hasBassBoost = true;
            } else if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_VIRTUALIZER)) {
                hasVirtualizer = true;
            }
            else if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_ENV_REVERB)) {
                hasEnvReverb = true;
            }
        }
        assertTrue("test0_0QueryEffects: equalizer not found", hasEQ);
        assertTrue("test0_0QueryEffects: bass boost not found", hasBassBoost);
        assertTrue("test0_0QueryEffects: virtualizer not found", hasVirtualizer);
        assertTrue("test0_0QueryEffects: environmental reverb not found", hasEnvReverb);
    }

    //-----------------------------------------------------------------
    // 1 - constructor
    //----------------------------------

    //Test case 1.0: test constructor from effect type and get effect ID
    @LargeTest
    public void test1_0ConstructorFromType() throws Exception {
        boolean result = true;
        String msg = "test1_0ConstructorFromType()";
        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
        assertTrue(msg+": no effects found", (desc.length != 0));
        try {
            AudioEffect effect = new AudioEffect(desc[0].type,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            try {
                assertTrue(msg +": invalid effect ID", (effect.getId() != 0));
            } catch (IllegalStateException e) {
                msg = msg.concat(": AudioEffect not initialized");
                result = false;
            } finally {
                effect.release();
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Effect not found: "+desc[0].name);
            result = false;
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            result = false;
        }
        assertTrue(msg, result);
    }

    //Test case 1.1: test constructor from effect uuid
    @LargeTest
    public void test1_1ConstructorFromUuid() throws Exception {
        boolean result = true;
        String msg = "test1_1ConstructorFromUuid()";
        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
        assertTrue(msg+"no effects found", (desc.length != 0));
        try {
            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_NULL,
                    desc[0].uuid,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            effect.release();
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Effect not found: "+desc[0].name);
            result = false;
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            result = false;
        }
        assertTrue(msg, result);
    }

    //Test case 1.2: test constructor failure from unknown type
    @LargeTest
    public void test1_2ConstructorUnknownType() throws Exception {
        boolean result = false;
        String msg = "test1_2ConstructorUnknownType()";

        try {
            AudioEffect effect = new AudioEffect(UUID.randomUUID(),
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            msg = msg.concat(": could create random AudioEffect");
            if (effect != null) {
                effect.release();
            }
        } catch (IllegalArgumentException e) {
            result = true;
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
        }
        assertTrue(msg, result);
    }

    //Test case 1.3: test getEnabled() failure when called on released effect
    @LargeTest
    public void test1_3GetEnabledAfterRelease() throws Exception {
        boolean result = false;
        String msg = "test1_3GetEnabledAfterRelease()";

        try {
            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            effect.release();
            try {
                effect.getEnabled();
            } catch (IllegalStateException e) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
        }
        assertTrue(msg, result);
    }

    //Test case 1.4: test contructor on mediaPlayer audio session
    @LargeTest
    public void test1_4InsertOnMediaPlayer() throws Exception {
        boolean result = false;
        String msg = "test1_4InsertOnMediaPlayer()";

        try {
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(MediaNames.SHORTMP3);

            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    mp.getAudioSessionId());
            assertNotNull(msg + ": could not create AudioEffect", effect);
            try {
                loge(msg, ": effect.setEnabled");
                effect.setEnabled(true);
            } catch (IllegalStateException e) {
                msg = msg.concat(": AudioEffect not initialized");
            }

            result = true;
            effect.release();
            mp.release();
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        } catch (Exception e){
            loge(msg, "Could not create media player:" + e);
        }
        assertTrue(msg, result);
    }

    //Test case 1.5: test auxiliary effect attachement on MediaPlayer
    @LargeTest
    public void test1_5AuxiliaryOnMediaPlayer() throws Exception {
        boolean result = false;
        String msg = "test1_5AuxiliaryOnMediaPlayer()";

        try {
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(MediaNames.SHORTMP3);

            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            mp.attachAuxEffect(effect.getId());
            mp.setAuxEffectSendLevel(1.0f);
            result = true;
            effect.release();
            mp.release();
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        } catch (Exception e){
            loge(msg, "Could not create media player:" + e);
        }
        assertTrue(msg, result);
    }

    //Test case 1.6: test auxiliary effect attachement failure before setDatasource
    @LargeTest
    public void test1_6AuxiliaryOnMediaPlayerFailure() throws Exception {
        boolean result = false;
        String msg = "test1_6AuxiliaryOnMediaPlayerFailure()";

        try {
            createMediaPlayerLooper();
            synchronized(lock) {
                try {
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Looper creation: wait was interrupted.");
                }
            }
            assertTrue(mInitialized);  // mMediaPlayer has been initialized?
            mError = 0;

            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            synchronized(lock) {
                try {
                    mMediaPlayer.attachAuxEffect(effect.getId());
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Attach effect: wait was interrupted.");
                }
            }
            assertTrue(msg + ": no error on attachAuxEffect", mError != 0);
            result = true;
            effect.release();
            terminateMediaPlayerLooper();
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        } catch (Exception e){
            loge(msg, "Could not create media player:" + e);
        }
        assertTrue(msg, result);
    }


    //Test case 1.7: test auxiliary effect attachement on AudioTrack
    @LargeTest
    public void test1_7AuxiliaryOnAudioTrack() throws Exception {
        boolean result = false;
        String msg = "test1_7AuxiliaryOnAudioTrack()";

        try {
            AudioTrack track = new AudioTrack(
                                        AudioManager.STREAM_MUSIC,
                                        44100,
                                        AudioFormat.CHANNEL_OUT_MONO,
                                        AudioFormat.ENCODING_PCM_16BIT,
                                        AudioTrack.getMinBufferSize(44100,
                                                                    AudioFormat.CHANNEL_OUT_MONO,
                                                                    AudioFormat.ENCODING_PCM_16BIT),
                                                                    AudioTrack.MODE_STREAM);
            assertNotNull(msg + ": could not create AudioTrack", track);
            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);

            track.attachAuxEffect(effect.getId());
            track.setAuxEffectSendLevel(1.0f);
            result = true;
            effect.release();
            track.release();
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // 2 - enable/ disable
    //----------------------------------


    //Test case 2.0: test setEnabled() and getEnabled() in valid state
    @LargeTest
    public void test2_0SetEnabledGetEnabled() throws Exception {
        boolean result = false;
        String msg = "test2_0SetEnabledGetEnabled()";

        try {
            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            try {
                effect.setEnabled(true);
                assertTrue(msg + ": invalid state from getEnabled", effect.getEnabled());
                effect.setEnabled(false);
                assertFalse(msg + ": invalid state to getEnabled", effect.getEnabled());
                result = true;
            } catch (IllegalStateException e) {
                msg = msg.concat(": setEnabled() in wrong state");
            } finally {
                effect.release();
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        }
        assertTrue(msg, result);
    }

    //Test case 2.1: test setEnabled() throws exception after release
    @LargeTest
    public void test2_1SetEnabledAfterRelease() throws Exception {
        boolean result = false;
        String msg = "test2_1SetEnabledAfterRelease()";

        try {
            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            effect.release();
            try {
                effect.setEnabled(true);
            } catch (IllegalStateException e) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // 3 - set parameters
    //----------------------------------

    //Test case 3.0: test setParameter(byte[], byte[])
    @LargeTest
    public void test3_0SetParameterByteArrayByteArray() throws Exception {
        boolean result = false;
        String msg = "test3_0SetParameterByteArrayByteArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            byte[] param = intToByteArray(Equalizer.PARAM_CURRENT_PRESET);
            byte[] value = shortToByteArray((short)0);
            if (effect.setParameter(param, value) == AudioEffect.SUCCESS) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("setParameter() called in wrong state");
            loge(msg, "setParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 3.1: test setParameter(int, int)
    @LargeTest
    public void test3_1SetParameterIntInt() throws Exception {
        boolean result = false;
        String msg = "test3_1SetParameterIntInt()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            if (effect.setParameter(EnvironmentalReverb.PARAM_DECAY_TIME, 0)
                    == AudioEffect.SUCCESS) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("setParameter() called in wrong state");
            loge(msg, "setParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 3.2: test setParameter(int, short)
    @LargeTest
    public void test3_2SetParameterIntShort() throws Exception {
        boolean result = false;
        String msg = "test3_2SetParameterIntShort()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            if (effect.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0)
                    == AudioEffect.SUCCESS) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("setParameter() called in wrong state");
            loge(msg, "setParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 3.3: test setParameter(int, byte[])
    @LargeTest
    public void test3_3SetParameterIntByteArray() throws Exception {
        boolean result = false;
        String msg = "test3_3SetParameterIntByteArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            byte[] value = shortToByteArray((short)0);
            if (effect.setParameter(Equalizer.PARAM_CURRENT_PRESET, value)
                    == AudioEffect.SUCCESS) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("setParameter() called in wrong state");
            loge(msg, "setParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 3.4: test setParameter(int[], int[])
    @LargeTest
    public void test3_4SetParameterIntArrayIntArray() throws Exception {
        boolean result = false;
        String msg = "test3_4SetParameterIntArrayIntArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            int[] param = new int[1];
            int[] value = new int[1];
            param[0] = EnvironmentalReverb.PARAM_DECAY_TIME;
            value[0] = 0;
            if (effect.setParameter(param, value)
                    == AudioEffect.SUCCESS) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("setParameter() called in wrong state");
            loge(msg, "setParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 3.5: test setParameter(int[], short[])
    @LargeTest
    public void test3_5SetParameterIntArrayShortArray() throws Exception {
        boolean result = false;
        String msg = "test3_5SetParameterIntArrayShortArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            int[] param = new int[1];
            short[] value = new short[1];
            param[0] = Equalizer.PARAM_CURRENT_PRESET;
            value[0] = (short)0;
            if (effect.setParameter(param, value)
                    == AudioEffect.SUCCESS) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("setParameter() called in wrong state");
            loge(msg, "setParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 3.6: test setParameter(int[], byte[])
    @LargeTest
    public void test3_6SetParameterIntArrayByteArray() throws Exception {
        boolean result = false;
        String msg = "test3_6SetParameterIntArrayByteArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            int[] param = new int[1];
            byte[] value = shortToByteArray((short)0);
            param[0] = Equalizer.PARAM_CURRENT_PRESET;
            if (effect.setParameter(param, value)
                    == AudioEffect.SUCCESS) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("setParameter() called in wrong state");
            loge(msg, "setParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 3.7: test setParameter() throws exception after release()
    @LargeTest
    public void test3_7SetParameterAfterRelease() throws Exception {
        boolean result = false;
        String msg = "test3_7SetParameterAfterRelease()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            effect.release();
            effect.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0);
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": setParameter() rejected");
            loge(msg, "setParameter() rejected");
        } catch (IllegalStateException e) {
            result = true;
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // 4 - get parameters
    //----------------------------------

    //Test case 4.0: test getParameter(byte[], byte[])
    @LargeTest
    public void test4_0GetParameterByteArrayByteArray() throws Exception {
        boolean result = false;
        String msg = "test4_0GetParameterByteArrayByteArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            byte[] param = intToByteArray(Equalizer.PARAM_CURRENT_PRESET);
            byte[] value = new byte[2];
            if (!AudioEffect.isError(effect.getParameter(param, value))) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("getParameter() called in wrong state");
            loge(msg, "getParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 4.1: test getParameter(int, int[])
    @LargeTest
    public void test4_1GetParameterIntIntArray() throws Exception {
        boolean result = false;
        String msg = "test4_1GetParameterIntIntArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            int[] value = new int[1];
            if (!AudioEffect.isError(
                    effect.getParameter(EnvironmentalReverb.PARAM_DECAY_TIME, value))) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("getParameter() called in wrong state");
            loge(msg, "getParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 4.2: test getParameter(int, short[])
    @LargeTest
    public void test4_2GetParameterIntShortArray() throws Exception {
        boolean result = false;
        String msg = "test4_2GetParameterIntShortArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            short[] value = new short[1];
            if (!AudioEffect.isError(effect.getParameter(Equalizer.PARAM_CURRENT_PRESET, value))) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("getParameter() called in wrong state");
            loge(msg, "getParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 4.3: test getParameter(int, byte[])
    @LargeTest
    public void test4_3GetParameterIntByteArray() throws Exception {
        boolean result = false;
        String msg = "test4_3GetParameterIntByteArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            byte[] value = new byte[2];
            if (!AudioEffect.isError(effect.getParameter(Equalizer.PARAM_CURRENT_PRESET, value))) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("getParameter() called in wrong state");
            loge(msg, "getParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 4.4: test getParameter(int[], int[])
    @LargeTest
    public void test4_4GetParameterIntArrayIntArray() throws Exception {
        boolean result = false;
        String msg = "test4_4GetParameterIntArrayIntArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            int[] param = new int[1];
            int[] value = new int[1];
            param[0] = EnvironmentalReverb.PARAM_DECAY_TIME;
            if (!AudioEffect.isError(effect.getParameter(param, value))) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("getParameter() called in wrong state");
            loge(msg, "getParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 4.5: test getParameter(int[], short[])
    @LargeTest
    public void test4_5GetParameterIntArrayShortArray() throws Exception {
        boolean result = false;
        String msg = "test4_5GetParameterIntArrayShortArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            int[] param = new int[1];
            short[] value = new short[1];
            param[0] = Equalizer.PARAM_CURRENT_PRESET;
            if (!AudioEffect.isError(effect.getParameter(param, value))) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("getParameter() called in wrong state");
            loge(msg, "getParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 4.6: test getParameter(int[], byte[])
    @LargeTest
    public void test4_6GetParameterIntArrayByteArray() throws Exception {
        boolean result = false;
        String msg = "test4_6GetParameterIntArrayByteArray()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            int[] param = new int[1];
            byte[] value = new byte[2];
            param[0] = Equalizer.PARAM_CURRENT_PRESET;
            if (!AudioEffect.isError(effect.getParameter(param, value))) {
                result = true;
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("getParameter() called in wrong state");
            loge(msg, "getParameter() called in wrong state");
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 4.7: test getParameter() throws exception after release()
    @LargeTest
    public void test4_7GetParameterAfterRelease() throws Exception {
        boolean result = false;
        String msg = "test4_7GetParameterAfterRelease()";
        AudioEffect effect = null;
        try {
            effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            effect.release();
            short[] value = new short[1];
            effect.getParameter(Equalizer.PARAM_CURRENT_PRESET, value);
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": getParameter() rejected");
            loge(msg, "getParameter() rejected");
        } catch (IllegalStateException e) {
            result = true;
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // 5 priority and listeners
    //----------------------------------

    //Test case 5.0: test control passed to higher priority client
    @LargeTest
    public void test5_0setEnabledLowerPriority() throws Exception {
        boolean result = false;
        String msg = "test5_0setEnabledLowerPriority()";
        AudioEffect effect1 = null;
        AudioEffect effect2 = null;
        try {
            effect1 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    1,
                    0);

            assertNotNull(msg + ": could not create AudioEffect", effect1);
            assertNotNull(msg + ": could not create AudioEffect", effect2);

            assertTrue(msg + ": Effect2 does not have control", effect2.hasControl());
            assertFalse(msg + ": Effect1 has control", effect1.hasControl());
            assertTrue(msg + ": Effect1 can enable",
                    effect1.setEnabled(true) == AudioEffect.ERROR_INVALID_OPERATION);
            assertFalse(msg + ": Effect1 has enabled", effect2.getEnabled());
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Effect not found");
            result = false;
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            result = false;
        } finally {
            if (effect1 != null) {
                effect1.release();
            }
            if (effect2 != null) {
                effect2.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 5.1: test control passed to higher priority client
    @LargeTest
    public void test5_1setParameterLowerPriority() throws Exception {
        boolean result = false;
        String msg = "test5_1setParameterLowerPriority()";
        AudioEffect effect1 = null;
        AudioEffect effect2 = null;
        try {
            effect1 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                                    AudioEffect.EFFECT_TYPE_NULL,
                                    0,
                                    0);
            effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    1,
                    0);

            assertNotNull(msg + ": could not create AudioEffect", effect1);
            assertNotNull(msg + ": could not create AudioEffect", effect2);

            int status = effect2.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0);
            assertEquals(msg + ": Effect2 setParameter failed",
                    AudioEffect.SUCCESS, status);

            status = effect1.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)1);
            assertEquals(msg + ": Effect1 setParameter did not fail",
                    AudioEffect.ERROR_INVALID_OPERATION, status);

            short[] value = new short[1];
            status = effect2.getParameter(Equalizer.PARAM_CURRENT_PRESET, value);
            assertFalse(msg + ": Effect2 getParameter failed",
                    AudioEffect.isError(status));
            assertEquals(msg + ": Effect1 changed parameter",
                    (short)0, value[0]);

            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Effect not found");
            result = false;
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            result = false;
        } finally {
            if (effect1 != null) {
                effect1.release();
            }
            if (effect2 != null) {
                effect2.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 5.2: test control status listener
    @LargeTest
    public void test5_2ControlStatusListener() throws Exception {
        boolean result = false;
        String msg = "test5_2ControlStatusListener()";
        mEffect = null;
        AudioEffect effect2 = null;
        try {
            mHasControl = true;
            createListenerLooper(true, false, false);
            synchronized(lock) {
                try {
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Looper creation: wait was interrupted.");
                }
            }
            assertTrue(mInitialized);
            synchronized(lock) {
                try {
                    effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                            AudioEffect.EFFECT_TYPE_NULL,
                            1,
                            0);
                    assertNotNull(msg + ": could not create AudioEffect", effect2);
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Create second effect: wait was interrupted.");
                }
            }
            assertFalse(msg + ": effect control not lost by effect1", mHasControl);
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        } catch (Exception e){
            loge(msg, "Could not create media player:" + e);
        } finally {
            terminateListenerLooper();
            if (effect2 != null) {
                effect2.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 5.3: test enable status listener
    @LargeTest
    public void test5_3EnableStatusListener() throws Exception {
        boolean result = false;
        String msg = "test5_3EnableStatusListener()";
        mEffect = null;
        AudioEffect effect2 = null;
        try {
            createListenerLooper(false, true, false);
            synchronized(lock) {
                try {
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Looper creation: wait was interrupted.");
                }
            }
            assertTrue(mInitialized);
            mEffect.setEnabled(true);
            mIsEnabled = true;
            effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    1,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect2);
            assertTrue(msg + ": effect not enabled", effect2.getEnabled());
            synchronized(lock) {
                try {
                    effect2.setEnabled(false);
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Create second effect: wait was interrupted.");
                }
            }
            assertFalse(msg + ": enable status not updated", mIsEnabled);
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        } catch (Exception e){
            loge(msg, "Could not create media player:" + e);
        } finally {
            terminateListenerLooper();
            if (effect2 != null) {
                effect2.release();
            }
        }
        assertTrue(msg, result);
    }

    //Test case 5.4: test parameter changed listener
    @LargeTest
    public void test5_4ParameterChangedListener() throws Exception {
        boolean result = false;
        String msg = "test5_4ParameterChangedListener()";
        mEffect = null;
        AudioEffect effect2 = null;
        try {
            createListenerLooper(false, false, true);
            synchronized(lock) {
                try {
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Looper creation: wait was interrupted.");
                }
            }
            assertTrue(mInitialized);
            effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    1,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect2);
            synchronized(lock) {
                try {
                    mParameterChanged = -1;
                    effect2.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0);
                    lock.wait(1000);
                } catch(Exception e) {
                    Log.e(TAG, "Create second effect: wait was interrupted.");
                }
            }
            assertEquals(msg + ": parameter change not received",
                    Equalizer.PARAM_CURRENT_PRESET, mParameterChanged);
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        } catch (Exception e){
            loge(msg, "Could not create media player:" + e);
        } finally {
            terminateListenerLooper();
            if (effect2 != null) {
                effect2.release();
            }
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // 6 command method
    //----------------------------------


    //Test case 6.0: test command method
    @LargeTest
    public void test6_0Command() throws Exception {
        boolean result = false;
        String msg = "test6_0Command()";
        AudioEffect effect = null;
        try {
             effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                    AudioEffect.EFFECT_TYPE_NULL,
                    0,
                    0);
            assertNotNull(msg + ": could not create AudioEffect", effect);
            try {
                byte[] cmd = new byte[0];
                byte[] reply = new byte[4];
                int status = effect.command(3, cmd, reply);
                assertFalse(msg + ": command failed", AudioEffect.isError(status));
                assertTrue(msg + ": effect not enabled", effect.getEnabled());
                result = true;
            } catch (IllegalStateException e) {
                msg = msg.concat(": command in illegal state");
            }
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Equalizer not found");
            loge(msg, ": Equalizer not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
            loge(msg, ": Effect library not loaded");
        } catch (Exception e){
            loge(msg, "Could not create media player:" + e);
        } finally {
            if (effect != null) {
                effect.release();
            }
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // private methods
    //----------------------------------

    /*
     * Initializes the message looper so that the MediaPlayer object can
     * receive the callback messages.
     */
    private void createMediaPlayerLooper() {
        new Thread() {
            @Override
            public void run() {
                // Set up a looper to be used by mMediaPlayer.
                Looper.prepare();

                // Save the looper so that we can terminate this thread
                // after we are done with it.
                mLooper = Looper.myLooper();

                mMediaPlayer = new MediaPlayer();
                mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    public boolean onError(MediaPlayer player, int what, int extra) {
                        synchronized(lock) {
                            mError = what;
                            lock.notify();
                        }
                        return true;
                    }
                });
                mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    public void onCompletion(MediaPlayer player) {
                        synchronized(lock) {
                            lock.notify();
                        }
                    }
                });
                synchronized(lock) {
                    mInitialized = true;
                    lock.notify();
                }
                Looper.loop();  // Blocks forever until Looper.quit() is called.
            }
        }.start();
    }
    /*
     * Terminates the message looper thread.
     */
    private void terminateMediaPlayerLooper() {
        if (mLooper != null) {
            mLooper.quit();
            mLooper = null;
        }
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
        }
    }

    /*
     * Initializes the message looper fro effect listener
     */
    class ListenerThread extends Thread {
        boolean mControl;
        boolean mEnable;
        boolean mParameter;

        public ListenerThread(boolean control, boolean enable, boolean parameter) {
            super();
            mControl = control;
            mEnable = enable;
            mParameter = parameter;
        }
    }
    private void createListenerLooper(boolean control, boolean enable, boolean parameter) {

        new ListenerThread(control, enable, parameter) {
            @Override
            public void run() {
                // Set up a looper to be used by mEffect.
                Looper.prepare();

                // Save the looper so that we can terminate this thread
                // after we are done with it.
                mLooper = Looper.myLooper();

                mEffect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                        AudioEffect.EFFECT_TYPE_NULL,
                        0,
                        0);
                assertNotNull("could not create AudioEffect", mEffect);

                if (mControl) {
                    mEffect.setControlStatusListener(new AudioEffect.OnControlStatusChangeListener() {
                        public void onControlStatusChange(AudioEffect effect, boolean controlGranted) {
                            synchronized(lock) {
                                if (effect == mEffect) {
                                    mHasControl = controlGranted;
                                    lock.notify();
                                }
                            }
                        }
                    });
                }
                if (mEnable) {
                    mEffect.setEnableStatusListener(new AudioEffect.OnEnableStatusChangeListener() {
                        public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
                            synchronized(lock) {
                                if (effect == mEffect) {
                                    mIsEnabled = enabled;
                                    lock.notify();
                                }
                            }
                        }
                    });
                }
                if (mParameter) {
                    mEffect.setParameterListener(new AudioEffect.OnParameterChangeListener() {
                        public void onParameterChange(AudioEffect effect, int status, byte[] param,
                                byte[] value) {
                            synchronized(lock) {
                                if (effect == mEffect) {
                                    mParameterChanged = byteArrayToInt(param);
                                    lock.notify();
                                }
                            }
                        }
                    });
                }

                synchronized(lock) {
                    mInitialized = true;
                    lock.notify();
                }
                Looper.loop();  // Blocks forever until Looper.quit() is called.
            }
        }.start();
    }
    /*
     * Terminates the listener looper thread.
     */
    private void terminateListenerLooper() {
        if (mEffect != null) {
            mEffect.release();
            mEffect = null;
        }
        if (mLooper != null) {
            mLooper.quit();
            mLooper = null;
        }
    }

    protected int byteArrayToInt(byte[] valueBuf) {
        return byteArrayToInt(valueBuf, 0);

    }

    protected int byteArrayToInt(byte[] valueBuf, int offset) {
        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
        converter.order(ByteOrder.nativeOrder());
        return converter.getInt(offset);

    }

    protected byte[] intToByteArray(int value) {
        ByteBuffer converter = ByteBuffer.allocate(4);
        converter.order(ByteOrder.nativeOrder());
        converter.putInt(value);
        return converter.array();
    }

    protected short byteArrayToShort(byte[] valueBuf) {
        return byteArrayToShort(valueBuf, 0);
    }

    protected short byteArrayToShort(byte[] valueBuf, int offset) {
        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
        converter.order(ByteOrder.nativeOrder());
        return converter.getShort(offset);

    }

    protected byte[] shortToByteArray(short value) {
        ByteBuffer converter = ByteBuffer.allocate(2);
        converter.order(ByteOrder.nativeOrder());
        short sValue = (short) value;
        converter.putShort(sValue);
        return converter.array();
    }

}

