/*
 * Copyright (C) 2015 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.cts.verifier.audio;

import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
import com.android.cts.verifier.audio.wavelib.*;
import com.android.compatibility.common.util.CddTest;
import com.android.compatibility.common.util.ReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;

import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.LinearLayout;
import android.widget.ProgressBar;

/**
 * Tests Audio built in Microphone response for Unprocessed audio source feature.
 */
@CddTest(requirement="5.11/C-1-1,C-1-2,C-1-3,C-1-4,C-1-5,C-1-6")
public class AudioFrequencyUnprocessedActivity extends AudioFrequencyActivity implements Runnable,
    AudioRecord.OnRecordPositionUpdateListener {
    private static final String TAG = "AudioFrequencyUnprocessedActivity";

    private static final int TEST_STARTED = 900;
    private static final int TEST_MESSAGE = 903;
    private static final int TEST_ENDED = 904;
    private static final int TEST_ENDED_ERROR = 905;
    private static final double MIN_FRACTION_POINTS_IN_BAND = 0.5;

    private static final double TONE_RMS_EXPECTED = -36.0;
    private static final double TONE_RMS_MAX_ERROR = 3.0;

    private static final double MAX_VAL = Math.pow(2, 15);
    private static final double CLIP_LEVEL = (MAX_VAL-10) / MAX_VAL;

    private static final int SOURCE_TONE = 0;
    private static final int SOURCE_NOISE = 1;

    private static final int TEST_NONE = -1;
    private static final int TEST_TONE = 0;
    private static final int TEST_NOISE = 1;
    private static final int TEST_USB_BACKGROUND = 2;
    private static final int TEST_USB_NOISE = 3;
    private static final int TEST_COUNT = 4;
    private int mCurrentTest = TEST_NONE;
    private boolean mTestsDone[] = new boolean[TEST_COUNT];

    private static final int TEST_DURATION_DEFAULT = 2000;
    private static final int TEST_DURATION_TONE = TEST_DURATION_DEFAULT;
    private static final int TEST_DURATION_NOISE = TEST_DURATION_DEFAULT;
    private static final int TEST_DURATION_USB_BACKGROUND = TEST_DURATION_DEFAULT;
    private static final int TEST_DURATION_USB_NOISE = TEST_DURATION_DEFAULT;

    final OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
    Context mContext;

    LinearLayout mLayoutTestTone;
    Button mButtonTestTone;
    ProgressBar mProgressTone;
    TextView mResultTestTone;
    Button mButtonPlayTone;

    LinearLayout mLayoutTestNoise;
    Button mButtonTestNoise;
    ProgressBar mProgressNoise;
    TextView mResultTestNoise;
    Button mButtonPlayNoise;

    LinearLayout mLayoutTestUsbBackground;
    Button mButtonTestUsbBackground;
    ProgressBar mProgressUsbBackground;
    TextView mResultTestUsbBackground;

    LinearLayout mLayoutTestUsbNoise;
    Button mButtonTestUsbNoise;
    ProgressBar mProgressUsbNoise;
    TextView mResultTestUsbNoise;
    Button mButtonPlayUsbNoise;

    TextView mGlobalResultText;
    TextView mTextViewUnprocessedStatus;

    private boolean mIsRecording = false;
    private final Object mRecordingLock = new Object();
    private AudioRecord mRecorder;
    private int mMinRecordBufferSizeInSamples = 0;
    private short[] mAudioShortArray;
    private short[] mAudioShortArray2;

    private final int mBlockSizeSamples = 4096;
    private final int mSamplingRate = 48000;
    private final int mSelectedRecordSource = MediaRecorder.AudioSource.UNPROCESSED;
    private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
    private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
    private Thread mRecordThread;

    PipeShort mPipe = new PipeShort(65536);

    SoundPlayerObject mSPlayer;

    private boolean mSupportsUnprocessed = false;

    private DspBufferComplex mC;
    private DspBufferDouble mData;

    private DspWindow mWindow;
    private DspFftServer mFftServer;
    private VectorAverage mFreqAverageTone = new VectorAverage();
    private VectorAverage mFreqAverageNoise = new VectorAverage();
    private VectorAverage mFreqAverageUsbBackground = new VectorAverage();
    private VectorAverage mFreqAverageUsbNoise = new VectorAverage();

    //RMS for tone:
    private double mRMS;
    private double mRMSMax;

    private double mRMSTone;
    private double mRMSMaxTone;

    int mBands = 3;
    int mBandsTone = 3;
    int mBandsBack = 3;
    AudioBandSpecs[] mBandSpecsMic = new AudioBandSpecs[mBands];
    AudioBandSpecs[] mBandSpecsTone = new AudioBandSpecs[mBandsTone];
    AudioBandSpecs[] mBandSpecsBack = new AudioBandSpecs[mBandsBack];
    private Results mResultsMic;
    private Results mResultsTone;
    private Results mResultsBack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.audio_frequency_unprocessed_activity);
        mContext = this;
        mTextViewUnprocessedStatus = (TextView) findViewById(
                R.id.audio_frequency_unprocessed_defined);
        //unprocessed test
        mSupportsUnprocessed = supportsUnprocessed();
        if (mSupportsUnprocessed) {
            mTextViewUnprocessedStatus.setText(
                    getResources().getText(R.string.audio_frequency_unprocessed_defined));
        } else {
            mTextViewUnprocessedStatus.setText(
                    getResources().getText(R.string.audio_frequency_unprocessed_not_defined));
        }

        mSPlayer = new SoundPlayerObject();
        playerSetSource(SOURCE_TONE);

        // Test tone
        mLayoutTestTone = (LinearLayout) findViewById(R.id.unprocessed_layout_test_tone);
        mButtonTestTone = (Button) findViewById(R.id.unprocessed_test_tone_btn);
        mButtonTestTone.setOnClickListener(mBtnClickListener);
        mProgressTone = (ProgressBar) findViewById(R.id.unprocessed_test_tone_progress_bar);
        mResultTestTone = (TextView) findViewById(R.id.unprocessed_test_tone_result);
        mButtonPlayTone = (Button) findViewById(R.id.unprocessed_play_tone_btn);
        mButtonPlayTone.setOnClickListener(mBtnClickListener);
        showWait(mProgressTone, false);

        //Test Noise
        mLayoutTestNoise = (LinearLayout) findViewById(R.id.unprocessed_layout_test_noise);
        mButtonTestNoise = (Button) findViewById(R.id.unprocessed_test_noise_btn);
        mButtonTestNoise.setOnClickListener(mBtnClickListener);
        mProgressNoise = (ProgressBar) findViewById(R.id.unprocessed_test_noise_progress_bar);
        mResultTestNoise = (TextView) findViewById(R.id.unprocessed_test_noise_result);
        mButtonPlayNoise = (Button) findViewById(R.id.unprocessed_play_noise_btn);
        mButtonPlayNoise.setOnClickListener(mBtnClickListener);
        showWait(mProgressNoise, false);

        //USB Background
        mLayoutTestUsbBackground = (LinearLayout)
                findViewById(R.id.unprocessed_layout_test_usb_background);
        mButtonTestUsbBackground = (Button) findViewById(R.id.unprocessed_test_usb_background_btn);
        mButtonTestUsbBackground.setOnClickListener(mBtnClickListener);
        mProgressUsbBackground = (ProgressBar)
                findViewById(R.id.unprocessed_test_usb_background_progress_bar);
        mResultTestUsbBackground = (TextView)
                findViewById(R.id.unprocessed_test_usb_background_result);
        showWait(mProgressUsbBackground, false);

        mLayoutTestUsbNoise = (LinearLayout) findViewById(R.id.unprocessed_layout_test_usb_noise);
        mButtonTestUsbNoise = (Button) findViewById(R.id.unprocessed_test_usb_noise_btn);
        mButtonTestUsbNoise.setOnClickListener(mBtnClickListener);
        mProgressUsbNoise = (ProgressBar)findViewById(R.id.unprocessed_test_usb_noise_progress_bar);
        mResultTestUsbNoise = (TextView) findViewById(R.id.unprocessed_test_usb_noise_result);
        mButtonPlayUsbNoise = (Button) findViewById(R.id.unprocessed_play_usb_noise_btn);
        mButtonPlayUsbNoise.setOnClickListener(mBtnClickListener);
        showWait(mProgressUsbNoise, false);

        setButtonPlayStatus(-1);
        mGlobalResultText = (TextView) findViewById(R.id.unprocessed_test_global_result);

        //Init FFT stuff
        mAudioShortArray2 = new short[mBlockSizeSamples*2];
        mData = new DspBufferDouble(mBlockSizeSamples);
        mC = new DspBufferComplex(mBlockSizeSamples);
        mFftServer = new DspFftServer(mBlockSizeSamples);

        int overlap = mBlockSizeSamples / 2;

        mWindow = new DspWindow(DspWindow.WINDOW_HANNING, mBlockSizeSamples, overlap);

        setPassFailButtonClickListeners();
        getPassButton().setEnabled(false);
        setInfoResources(R.string.audio_frequency_unprocessed_test,
                R.string.audio_frequency_unprocessed_info, -1);

        //Init bands for Mic test
        mBandSpecsMic[0] = new AudioBandSpecs(
                5, 100,          /* frequency start,stop */
                20.0, -20.0,     /* start top,bottom value */
                20.0, -20.0      /* stop top,bottom value */);

        mBandSpecsMic[1] = new AudioBandSpecs(
                100, 7000,       /* frequency start,stop */
                10.0, -10.0,     /* start top,bottom value */
                10.0, -10.0      /* stop top,bottom value */);

        mBandSpecsMic[2] = new AudioBandSpecs(
                7000, 20000,     /* frequency start,stop */
                30.0, -30.0,     /* start top,bottom value */
                30.0, -30.0      /* stop top,bottom value */);

        //Init bands for Tone test
        mBandSpecsTone[0] = new AudioBandSpecs(
                5, 900,          /* frequency start,stop */
                -10.0, -100.0,     /* start top,bottom value */
                -10.0, -100.0      /* stop top,bottom value */);

        mBandSpecsTone[1] = new AudioBandSpecs(
                900, 1100,       /* frequency start,stop */
                10.0, -50.0,     /* start top,bottom value */
                10.0, -10.0      /* stop top,bottom value */);

        mBandSpecsTone[2] = new AudioBandSpecs(
                1100, 20000,     /* frequency start,stop */
                -30.0, -120.0,     /* start top,bottom value */
                -30.0, -120.0      /* stop top,bottom value */);

      //Init bands for Background test
        mBandSpecsBack[0] = new AudioBandSpecs(
                5, 100,          /* frequency start,stop */
                10.0, -120.0,     /* start top,bottom value */
                -10.0, -120.0      /* stop top,bottom value */);

        mBandSpecsBack[1] = new AudioBandSpecs(
                100, 7000,       /* frequency start,stop */
                -10.0, -120.0,     /* start top,bottom value */
                -50.0, -120.0      /* stop top,bottom value */);

        mBandSpecsBack[2] = new AudioBandSpecs(
                7000, 20000,     /* frequency start,stop */
                -50.0, -120.0,     /* start top,bottom value */
                -50.0, -120.0      /* stop top,bottom value */);

        mSupportsUnprocessed = supportsUnprocessed();
        Log.v(TAG, "Supports unprocessed: " + mSupportsUnprocessed);

        mResultsMic =  new Results("mic_response", mBands);
        mResultsTone = new Results("tone_response", mBandsTone);
        mResultsBack = new Results("background_response", mBandsBack);
    }

    private void playerToggleButton(int buttonId, int sourceId) {
        if (playerIsPlaying()) {
            playerStopAll();
        } else {
            playerSetSource(sourceId);
            playerTransport(true);
            setButtonPlayStatus(buttonId);
        }
    }

    private class OnBtnClickListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            int id = v.getId();
            switch (id) {
            case R.id.unprocessed_test_tone_btn:
                startTest(TEST_TONE);
                break;
            case R.id.unprocessed_play_tone_btn:
                playerToggleButton(id, SOURCE_TONE);
                break;
            case R.id.unprocessed_test_noise_btn:
                startTest(TEST_NOISE);
                break;
            case R.id.unprocessed_play_noise_btn:
                playerToggleButton(id, SOURCE_NOISE);
                break;
            case R.id.unprocessed_test_usb_background_btn:
                startTest(TEST_USB_BACKGROUND);
                break;
            case R.id.unprocessed_test_usb_noise_btn:
                startTest(TEST_USB_NOISE);
                break;
            case R.id.unprocessed_play_usb_noise_btn:
                playerToggleButton(id, SOURCE_NOISE);
                break;
            }
        }
    }

    private void setButtonPlayStatus(int playResId) {
        String play = getResources().getText(R.string.unprocessed_play).toString();
        String stop = getResources().getText(R.string.unprocessed_stop).toString();

        mButtonPlayTone.setText(playResId == R.id.unprocessed_play_tone_btn ? stop : play);
        mButtonPlayNoise.setText(playResId == R.id.unprocessed_play_noise_btn ? stop : play);
        mButtonPlayUsbNoise.setText(playResId ==
                R.id.unprocessed_play_usb_noise_btn ? stop : play);
    }

    private void playerSetSource(int sourceIndex) {
        switch (sourceIndex) {
            case SOURCE_TONE:
                mSPlayer.setSoundWithResId(getApplicationContext(), R.raw.onekhztone);
                break;
            default:
            case SOURCE_NOISE:
                mSPlayer.setSoundWithResId(getApplicationContext(),
                        R.raw.stereo_mono_white_noise_48);
                break;
        }
    }

    private void playerTransport(boolean play) {
        if (!mSPlayer.isAlive()) {
            mSPlayer.start();
        }
        mSPlayer.play(play);
    }

    private boolean playerIsPlaying() {
       return mSPlayer.isPlaying();
    }

    private void playerStopAll() {
        if (mSPlayer.isAlive() && mSPlayer.isPlaying()) {
            mSPlayer.play(false);
            setButtonPlayStatus(-1);
        }
    }

    /**
     * enable test ui elements
     */
    private void enableLayout(LinearLayout layout, boolean enable) {
        for (int i = 0; i < layout.getChildCount(); i++) {
            View view = layout.getChildAt(i);
            view.setEnabled(enable);
        }
    }

    private void showWait(ProgressBar pb, boolean show) {
        if (show) {
            pb.setVisibility(View.VISIBLE);
        } else {
            pb.setVisibility(View.INVISIBLE);
        }
    }

    private String getTestString(int testId) {
        String name = "undefined";
        switch(testId) {
            case TEST_TONE:
                name = "BuiltIn_tone";
                break;
            case TEST_NOISE:
                name = "BuiltIn_noise";
                break;
            case TEST_USB_BACKGROUND:
                name = "USB_background";
                break;
            case TEST_USB_NOISE:
                name = "USB_noise";
                break;
        }
        return name;
    }

    private void showWait(int testId, boolean show) {
        switch(testId) {
            case TEST_TONE:
                showWait(mProgressTone, show);
                break;
            case TEST_NOISE:
                showWait(mProgressNoise, show);
                break;
            case TEST_USB_BACKGROUND:
                showWait(mProgressUsbBackground, show);
                break;
            case TEST_USB_NOISE:
                showWait(mProgressUsbNoise, show);
                break;
        }
    }

    private void showMessage(int testId, String msg) {
        if (msg != null && msg.length() > 0) {
            switch(testId) {
                case TEST_TONE:
                    mResultTestTone.setText(msg);
                    break;
                case TEST_NOISE:
                    mResultTestNoise.setText(msg);
                    break;
                case TEST_USB_BACKGROUND:
                    mResultTestUsbBackground.setText(msg);
                    break;
                case TEST_USB_NOISE:
                    mResultTestUsbNoise.setText(msg);
                    break;
            }
        }
    }

    private boolean supportsUnprocessed() {
        boolean unprocessedSupport = false;
        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        String unprocessedSupportString = am.getProperty(
                AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED);
        Log.v(TAG,"unprocessed support: " + unprocessedSupportString);
        if (unprocessedSupportString == null ||
                unprocessedSupportString.equalsIgnoreCase(getResources().getString(
                        R.string.audio_general_default_false_string))) {
            unprocessedSupport = false;
        } else {
            unprocessedSupport = true;
        }
        return unprocessedSupport;
    }

    private void computeAllResults() {
        StringBuilder sb = new StringBuilder();

        boolean allDone = true;

        for (int i=0; i<TEST_COUNT; i++) {
            allDone = allDone & mTestsDone[i];
            sb.append(String.format("%s : %s\n", getTestString(i),
                    mTestsDone[i] ? "DONE" :" NOT DONE"));
        }

        if (allDone) {
            sb.append(computeResults());
        } else {
            sb.append("Please execute all tests for results\n");
        }
        mGlobalResultText.setText(sb.toString());
    }

    private void processSpectrum(Results results, AudioBandSpecs[] bandsSpecs, int anchorBand) {
        int points = results.mValuesLog.length;
        int bandCount = bandsSpecs.length;
        int currentBand = 0;
        for (int i = 0; i < points; i++) {
            double freq = (double)mSamplingRate * i / (double)mBlockSizeSamples;
            if (freq > bandsSpecs[currentBand].mFreqStop) {
                currentBand++;
                if (currentBand >= bandCount)
                    break;
            }

            if (freq >= bandsSpecs[currentBand].mFreqStart) {
                results.mAverageEnergyPerBand[currentBand] += results.mValuesLog[i];
                results.mPointsPerBand[currentBand]++;
            }
        }

        for (int b = 0; b < bandCount; b++) {
            if (results.mPointsPerBand[b] > 0) {
                results.mAverageEnergyPerBand[b] =
                        results.mAverageEnergyPerBand[b] / results.mPointsPerBand[b];
            }
        }

        //set offset relative to band anchor band level
        for (int b = 0; b < bandCount; b++) {
            if (anchorBand > -1 && anchorBand < bandCount) {
                bandsSpecs[b].setOffset(results.mAverageEnergyPerBand[anchorBand]);
            } else {
                bandsSpecs[b].setOffset(0);
            }
        }

        //test points in band.
        currentBand = 0;
        for (int i = 0; i < points; i++) {
            double freq = (double) mSamplingRate * i / (double) mBlockSizeSamples;
            if (freq >  bandsSpecs[currentBand].mFreqStop) {
                currentBand++;
                if (currentBand >= bandCount)
                    break;
            }

            if (freq >= bandsSpecs[currentBand].mFreqStart) {
                double value = results.mValuesLog[i];
                if (bandsSpecs[currentBand].isInBounds(freq, value)) {
                    results.mInBoundPointsPerBand[currentBand]++;
                }
            }
        }
    }

    private String computeResults() {
        StringBuilder sb = new StringBuilder();

        int points = mFreqAverageNoise.getSize();
        //mFreqAverageNoise size is determined by the latest data writen to it.
        //Currently, this data is always mBlockSizeSamples/2.
        if (points < 1) {
            return "error: not enough points";
        }

        double[] tone = new double[points];
        double[] noise = new double[points];
        double[] reference = new double[points];
        double[] background = new double[points];

        mFreqAverageTone.getData(tone, false);
        mFreqAverageNoise.getData(noise, false);
        mFreqAverageUsbNoise.getData(reference, false);
        mFreqAverageUsbBackground.getData(background, false);

        //Convert to dB
        double[] toneDb = new double[points];
        double[] noiseDb = new double[points];
        double[] referenceDb = new double[points];
        double[] backgroundDb = new double[points];

        double[] compensatedNoiseDb = new double[points];

        for (int i = 0; i < points; i++) {
            toneDb[i] = 20 * Math.log10(tone[i]);
            noiseDb[i] = 20 * Math.log10(noise[i]);
            referenceDb[i] = 20 * Math.log10(reference[i]);
            backgroundDb[i] = 20 * Math.log10(background[i]);

            compensatedNoiseDb[i] = noiseDb[i] - referenceDb[i];
        }

        mResultsMic.reset();
        mResultsTone.reset();
        mResultsBack.reset();

        mResultsMic.mValuesLog = compensatedNoiseDb;
        mResultsTone.mValuesLog = toneDb;
        mResultsBack.mValuesLog = backgroundDb;

        processSpectrum(mResultsMic, mBandSpecsMic, 1);
        processSpectrum(mResultsTone, mBandSpecsTone, 1);
        processSpectrum(mResultsBack, mBandSpecsBack, -1); //no reference for offset

        //Tone test
        boolean toneTestSuccess = true;
        {
            //rms level should be -36 dbfs +/- 3 db?
            double rmsMaxDb =  20 * Math.log10(mRMSMaxTone);
            sb.append(String.format("RMS level of tone: %.2f dBFS\n", rmsMaxDb));
            sb.append(String.format("Target RMS level: %.2f dBFS +/- %.2f dB\n",
                    TONE_RMS_EXPECTED,
                    TONE_RMS_MAX_ERROR));
            if (Math.abs(rmsMaxDb - TONE_RMS_EXPECTED) > TONE_RMS_MAX_ERROR) {
                toneTestSuccess = false;
                sb.append("RMS level test FAILED\n");
            } else {
                sb.append(" RMS level test SUCCESSFUL\n");
            }
            //check the spectrum is really a tone around 1 khz
        }

        sb.append("\n");
        sb.append(mResultsTone.toString());
        if (mResultsTone.testAll()) {
            sb.append(" 1 Khz Tone Frequency Response Test SUCCESSFUL\n");
        } else {
            sb.append(" 1 Khz Tone Frequency Response Test FAILED\n");
        }
        sb.append("\n");

        sb.append("\n");
        sb.append(mResultsBack.toString());
        if (mResultsBack.testAll()) {
            sb.append(" Background environment Test SUCCESSFUL\n");
        } else {
            sb.append(" Background environment Test FAILED\n");
        }

        sb.append("\n");
        sb.append(mResultsMic.toString());
        if (mResultsMic.testAll()) {
            sb.append(" Frequency Response Test SUCCESSFUL\n");
        } else {
            sb.append(" Frequency Response Test FAILED\n");
        }
        sb.append("\n");

        recordTestResults(mResultsTone);
        recordTestResults(mResultsMic);

        boolean allTestsPassed = false;
        if (mResultsMic.testAll() && mResultsTone.testAll() && toneTestSuccess &&
                mResultsBack.testAll()) {
            allTestsPassed = true;
            String strSuccess = getResources().getString(R.string.audio_general_test_passed);
            sb.append(strSuccess);
        } else {
            String strFailed = getResources().getString(R.string.audio_general_test_failed);
            sb.append(strFailed);
        }

        sb.append("\n");
        if (mSupportsUnprocessed) { //test is mandatory
            sb.append(getResources().getText(
                    R.string.audio_frequency_unprocessed_defined).toString());
            if (allTestsPassed) {
                getPassButton().setEnabled(true);
            } else {
                getPassButton().setEnabled(false);
            }
        } else {
            //test optional
            sb.append(getResources().getText(
                    R.string.audio_frequency_unprocessed_not_defined).toString());
            getPassButton().setEnabled(true);
        }
        return sb.toString();
    }

    Thread mTestThread;
    private void startTest(int testId) {
        if (mTestThread != null && !mTestThread.isAlive()) {
            mTestThread = null; //kill it.
        }

        if (mTestThread == null) {
            mRMS = 0;
            mRMSMax = 0;
            Log.v(TAG,"Executing test Thread");
            switch(testId) {
                case TEST_TONE:
                    mTestThread = new Thread(new TestRunnable(TEST_TONE) {
                        public void run() {
                            super.run();
                            if (!mUsbMicConnected) {
                                sendMessage(mTestId, TEST_MESSAGE,
                                        "Testing Built in Microphone: Tone");
                                mRMSTone = 0;
                                mRMSMaxTone = 0;
                                mFreqAverageTone.reset();
                                mFreqAverageTone.setCaptureType(VectorAverage.CAPTURE_TYPE_MAX);
                                record(TEST_DURATION_TONE);
                                sendMessage(mTestId, TEST_ENDED, "Testing Completed");
                                mTestsDone[mTestId] = true;
                            } else {
                                sendMessage(mTestId, TEST_ENDED_ERROR,
                                        "Please Unplug USB Microphone");
                                mTestsDone[mTestId] = false;
                            }
                        }
                    });
                break;
                case TEST_NOISE:
                    mTestThread = new Thread(new TestRunnable(TEST_NOISE) {
                        public void run() {
                            super.run();
                            if (!mUsbMicConnected) {
                                sendMessage(mTestId, TEST_MESSAGE,
                                        "Testing Built in Microphone: Noise");
                                mFreqAverageNoise.reset();
                                mFreqAverageNoise.setCaptureType(VectorAverage.CAPTURE_TYPE_MAX);
                                record(TEST_DURATION_NOISE);
                                sendMessage(mTestId, TEST_ENDED, "Testing Completed");
                                mTestsDone[mTestId] = true;
                            } else {
                                sendMessage(mTestId, TEST_ENDED_ERROR,
                                        "Please Unplug USB Microphone");
                                mTestsDone[mTestId] = false;
                            }
                        }
                    });
                break;
                case TEST_USB_BACKGROUND:
                    playerStopAll();
                    mTestThread = new Thread(new TestRunnable(TEST_USB_BACKGROUND) {
                        public void run() {
                            super.run();
                            if (mUsbMicConnected) {
                                sendMessage(mTestId, TEST_MESSAGE,
                                        "Testing USB Microphone: background");
                                mFreqAverageUsbBackground.reset();
                                mFreqAverageUsbBackground.setCaptureType(
                                        VectorAverage.CAPTURE_TYPE_AVERAGE);
                                record(TEST_DURATION_USB_BACKGROUND);
                                sendMessage(mTestId, TEST_ENDED, "Testing Completed");
                                mTestsDone[mTestId] = true;
                            } else {
                                sendMessage(mTestId, TEST_ENDED_ERROR,
                                        "USB Microphone not detected.");
                                mTestsDone[mTestId] = false;
                            }
                        }
                    });
                break;
                case TEST_USB_NOISE:
                    mTestThread = new Thread(new TestRunnable(TEST_USB_NOISE) {
                        public void run() {
                            super.run();
                            if (mUsbMicConnected) {
                                sendMessage(mTestId, TEST_MESSAGE, "Testing USB Microphone: Noise");
                                mFreqAverageUsbNoise.reset();
                                mFreqAverageUsbNoise.setCaptureType(VectorAverage.CAPTURE_TYPE_MAX);
                                record(TEST_DURATION_USB_NOISE);
                                sendMessage(mTestId, TEST_ENDED, "Testing Completed");
                                mTestsDone[mTestId] = true;
                            } else {
                                sendMessage(mTestId, TEST_ENDED_ERROR,
                                        "USB Microphone not detected.");
                                mTestsDone[mTestId] = false;
                            }
                        }
                    });
                break;
            }
            mTestThread.start();
        } else {
            Log.v(TAG,"test Thread already running.");
        }
    }
    public class TestRunnable implements Runnable {
        public int mTestId;
        public boolean mUsbMicConnected;
        TestRunnable(int testId) {
            Log.v(TAG,"New TestRunnable");
            mTestId = testId;
        }
        public void run() {
            mCurrentTest = mTestId;
            sendMessage(mTestId, TEST_STARTED,"");
            mUsbMicConnected =
                    UsbMicrophoneTester.getIsMicrophoneConnected(getApplicationContext());
        };
        public void record(int durationMs) {
            startRecording();
            try {
                Thread.sleep(durationMs);
            } catch (InterruptedException e) {
                e.printStackTrace();
                //restore interrupted status
                Thread.currentThread().interrupt();
            }
            stopRecording();
        }
        public void sendMessage(int testId, int msgType, String str) {
            Message msg = Message.obtain();
            msg.what = msgType;
            msg.obj = str;
            msg.arg1 = testId;
            mMessageHandler.sendMessage(msg);
        }
    }

    private Handler mMessageHandler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int testId = msg.arg1; //testId
            String str = (String) msg.obj;
            switch (msg.what) {
            case TEST_STARTED:
                showWait(testId, true);
//                getPassButton().setEnabled(false);
                break;
            case TEST_MESSAGE:
                    showMessage(testId, str);
                break;
            case TEST_ENDED:
                showWait(testId, false);
                playerStopAll();
                showMessage(testId, str);
                appendResultsToScreen(testId, "test finished");
                computeAllResults();
                break;
            case TEST_ENDED_ERROR:
                showWait(testId, false);
                playerStopAll();
                showMessage(testId, str);
                computeAllResults();
            default:
                Log.e(TAG, String.format("Unknown message: %d", msg.what));
            }
        }
    };

    private class Results {
        private int mBandCount;
        private String mLabel;
        public double[] mValuesLog;
        int[] mPointsPerBand; // = new int[mBands];
        double[] mAverageEnergyPerBand;// = new double[mBands];
        int[] mInBoundPointsPerBand;// = new int[mBands];
        public Results(String label, int bandCount) {
            mLabel = label;
            mBandCount = bandCount;
            mPointsPerBand = new int[mBandCount];
            mAverageEnergyPerBand = new double[mBandCount];
            mInBoundPointsPerBand = new int[mBandCount];
        }
        public void reset() {
            for (int i = 0; i < mBandCount; i++) {
                mPointsPerBand[i] = 0;
                mAverageEnergyPerBand[i] = 0;
                mInBoundPointsPerBand[i] = 0;
            }
        }

        //append results
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(String.format("Channel %s\n", mLabel));
            for (int b = 0; b < mBandCount; b++) {
                double percent = 0;
                if (mPointsPerBand[b] > 0) {
                    percent = 100.0 * (double) mInBoundPointsPerBand[b] / mPointsPerBand[b];
                }
                sb.append(String.format(
                        " Band %d: Av. Level: %.1f dB InBand: %d/%d (%.1f%%) %s\n",
                        b, mAverageEnergyPerBand[b],
                        mInBoundPointsPerBand[b],
                        mPointsPerBand[b],
                        percent,
                        (testInBand(b) ? "OK" : "Not Optimal")));
            }
            return sb.toString();
        }

        public boolean testInBand(int b) {
            if (b >= 0 && b < mBandCount && mPointsPerBand[b] > 0) {
                if ((double) mInBoundPointsPerBand[b] / mPointsPerBand[b] >
                    MIN_FRACTION_POINTS_IN_BAND) {
                        return true;
                }
            }
            return false;
        }

        public boolean testAll() {
            for (int b = 0; b < mBandCount; b++) {
                if (!testInBand(b)) {
                    return false;
                }
            }
            return true;
        }
    }


//    /**
//     * compute test results
//     */
//    private void computeTestResults(int testId) {
//        String testName = getTestString(testId);
//        appendResultsToScreen(testId, "test finished");
//    }

    //append results
    private void appendResultsToScreen(String str, TextView text) {
        String currentText = text.getText().toString();
        text.setText(currentText + "\n" + str);
    }

    private void appendResultsToScreen(int testId, String str) {
        switch(testId) {
            case TEST_TONE:
                appendResultsToScreen(str, mResultTestTone);
                showToneRMS();
                break;
            case TEST_NOISE:
                appendResultsToScreen(str, mResultTestNoise);
                break;
            case TEST_USB_BACKGROUND:
                appendResultsToScreen(str, mResultTestUsbBackground);
                break;
            case TEST_USB_NOISE:
                appendResultsToScreen(str, mResultTestUsbNoise);
                break;
        }
    }

    /**
     * Store test results in log
     */
    private void recordTestResults(Results results) {
        String channelLabel = "channel_" + results.mLabel;

        for (int b = 0; b < mBands; b++) {
            String bandLabel = String.format(channelLabel + "_%d", b);
            getReportLog().addValue(
                    bandLabel + "_Level",
                    results.mAverageEnergyPerBand[b],
                    ResultType.HIGHER_BETTER,
                    ResultUnit.NONE);

            getReportLog().addValue(
                    bandLabel + "_pointsinbound",
                    results.mInBoundPointsPerBand[b],
                    ResultType.HIGHER_BETTER,
                    ResultUnit.COUNT);

            getReportLog().addValue(
                    bandLabel + "_pointstotal",
                    results.mPointsPerBand[b],
                    ResultType.NEUTRAL,
                    ResultUnit.COUNT);
        }

        getReportLog().addValues(channelLabel + "_magnitudeSpectrumLog",
                results.mValuesLog,
                ResultType.NEUTRAL,
                ResultUnit.NONE);

        Log.v(TAG, "Results Recorded");
    }

    private void recordHeasetPortFound(boolean found) {
        getReportLog().addValue(
                "User Reported Headset Port",
                found ? 1.0 : 0,
                ResultType.NEUTRAL,
                ResultUnit.NONE);
    }

    private void startRecording() {
        synchronized (mRecordingLock) {
            mIsRecording = true;
        }

        boolean successful = initRecord();
        if (successful) {
            startRecordingForReal();
        } else {
            Log.v(TAG, "Recorder initialization error.");
            synchronized (mRecordingLock) {
                mIsRecording = false;
            }
        }
    }

    private void startRecordingForReal() {
        // start streaming
        if (mRecordThread == null) {
            mRecordThread = new Thread(AudioFrequencyUnprocessedActivity.this);
            mRecordThread.setName("FrequencyAnalyzerThread");
        }
        if (!mRecordThread.isAlive()) {
            mRecordThread.start();
        }

        mPipe.flush();

        long startTime = SystemClock.uptimeMillis();
        mRecorder.startRecording();
        if (mRecorder.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
            stopRecording();
            return;
        }
        Log.v(TAG, "Start time: " + (long) (SystemClock.uptimeMillis() - startTime) + " ms");
    }

    private void stopRecording() {
        synchronized (mRecordingLock) {
            stopRecordingForReal();
            mIsRecording = false;
        }
    }

    private void stopRecordingForReal() {

        // stop streaming
        Thread zeThread = mRecordThread;
        mRecordThread = null;
        if (zeThread != null) {
            zeThread.interrupt();
            try {
                zeThread.join();
            } catch(InterruptedException e) {
                //restore interrupted status of recording thread
                zeThread.interrupt();
            }
        }
         // release recording resources
        if (mRecorder != null) {
            mRecorder.stop();
            mRecorder.release();
            mRecorder = null;
        }
    }

    private boolean initRecord() {
        int minRecordBuffSizeInBytes = AudioRecord.getMinBufferSize(mSamplingRate,
                mChannelConfig, mAudioFormat);
        Log.v(TAG,"FrequencyAnalyzer: min buff size = " + minRecordBuffSizeInBytes + " bytes");
        if (minRecordBuffSizeInBytes <= 0) {
            return false;
        }

        mMinRecordBufferSizeInSamples = minRecordBuffSizeInBytes / 2;
        // allocate the byte array to read the audio data

        mAudioShortArray = new short[mMinRecordBufferSizeInSamples];

        Log.v(TAG, "Initiating record:");
        Log.v(TAG, "      using source " + mSelectedRecordSource);
        Log.v(TAG, "      at " + mSamplingRate + "Hz");

        try {
            mRecorder = new AudioRecord(mSelectedRecordSource, mSamplingRate,
                    mChannelConfig, mAudioFormat, 2 * minRecordBuffSizeInBytes);
        } catch (IllegalArgumentException e) {
            return false;
        }
        if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
            mRecorder.release();
            mRecorder = null;
            return false;
        }
        mRecorder.setRecordPositionUpdateListener(this);
        mRecorder.setPositionNotificationPeriod(mBlockSizeSamples / 2);
        return true;
    }
    private void showToneRMS() {
        String str = String.format("RMS: %.3f dBFS. Max RMS: %.3f dBFS",
                20 * Math.log10(mRMSTone),
                20 * Math.log10(mRMSMaxTone));
        showMessage(TEST_TONE, str);
    }

    // ---------------------------------------------------------
    // Implementation of AudioRecord.OnPeriodicNotificationListener
    // --------------------
    public void onPeriodicNotification(AudioRecord recorder) {
        int samplesAvailable = mPipe.availableToRead();
        int samplesNeeded = mBlockSizeSamples;
        if (samplesAvailable >= samplesNeeded) {
            mPipe.read(mAudioShortArray2, 0, samplesNeeded);

            //compute stuff.
            int clipcount = 0;
//            double sum = 0;
            double maxabs = 0;
            int i;
            double rmsTempSum = 0;

            for (i = 0; i < samplesNeeded; i++) {
                double value = mAudioShortArray2[i] / MAX_VAL;
                double valueabs = Math.abs(value);

                if (valueabs > maxabs) {
                    maxabs = valueabs;
                }

                if (valueabs > CLIP_LEVEL) {
                    clipcount++;
                }

                rmsTempSum += value * value;
                //fft stuff
                mData.mData[i] = value;
            }
            double rms = Math.sqrt(rmsTempSum / samplesNeeded);

            double alpha = 0.9;
            double total_rms = rms * alpha + mRMS *(1-alpha);
            mRMS = total_rms;
            if (mRMS > mRMSMax) {
                mRMSMax = mRMS;
            }

            //for the current frame, compute FFT and send to the viewer.

            //apply window and pack as complex for now.
            DspBufferMath.mult(mData, mData, mWindow.mBuffer);
            DspBufferMath.set(mC, mData);
            mFftServer.fft(mC, 1);

            double[] halfMagnitude = new double[mBlockSizeSamples / 2];
            for (i = 0; i < mBlockSizeSamples / 2; i++) {
                halfMagnitude[i] = Math.sqrt(mC.mReal[i] * mC.mReal[i] + mC.mImag[i] * mC.mImag[i]);
            }

            switch(mCurrentTest) {
                case TEST_TONE: {
                    mFreqAverageTone.setData(halfMagnitude, false);
                    //Update realtime info on screen
                    mRMSTone = mRMS;
                    mRMSMaxTone = mRMSMax;
                   showToneRMS();
                }
                    break;
                case TEST_NOISE:
                    mFreqAverageNoise.setData(halfMagnitude, false);
                    break;
                case TEST_USB_BACKGROUND:
                    mFreqAverageUsbBackground.setData(halfMagnitude, false);
                    break;
                case TEST_USB_NOISE:
                    mFreqAverageUsbNoise.setData(halfMagnitude, false);
                    break;
            }
        }
    }

    public void onMarkerReached(AudioRecord track) {
    }

    // ---------------------------------------------------------
    // Implementation of Runnable for the audio recording + playback
    // --------------------
    public void run() {
        Thread thisThread = Thread.currentThread();
        while (!thisThread.isInterrupted()) {
            // read from native recorder
            int nSamplesRead = mRecorder.read(mAudioShortArray, 0, mMinRecordBufferSizeInSamples);
            if (nSamplesRead > 0) {
                mPipe.write(mAudioShortArray, 0, nSamplesRead);
            }
        }
    }
}
