/*
 * 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 (effect.getParameter(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(": 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 (effect.getParameter(EnvironmentalReverb.PARAM_DECAY_TIME, 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(": 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 (effect.getParameter(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(": 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 (effect.getParameter(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(": 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 (effect.getParameter(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(": 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 (effect.getParameter(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(": 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 (effect.getParameter(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(": 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);
            assertEquals(msg + ": Effect2 getParameter failed",
                    AudioEffect.SUCCESS, 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);
                assertEquals(msg + ": command failed", AudioEffect.SUCCESS, 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();
    }

}

