/*
 * Copyright (C) 2019 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 android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
import com.android.cts.verifier.audio.soundio.SoundPlayerObject;
import com.android.cts.verifier.audio.soundio.SoundRecorderObject;
import com.android.cts.verifier.CtsVerifierReportLog;
import com.android.cts.verifier.R;
import com.android.cts.verifier.audio.wavelib.DspBufferComplex;
import com.android.cts.verifier.audio.wavelib.DspBufferDouble;
import com.android.cts.verifier.audio.wavelib.DspBufferMath;
import com.android.cts.verifier.audio.wavelib.DspFftServer;
import com.android.cts.verifier.audio.wavelib.DspWindow;
import com.android.cts.verifier.audio.wavelib.VectorAverage;

/**
 * Tests Audio built in Microphone response for Voice Recognition audio source feature.
 */
public class AudioFrequencyVoiceRecognitionActivity extends AudioFrequencyActivity {
    private static final String TAG = "VoiceRecognition";

    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 = -22.35; //VOICE_RECOGNITION levels
    private static final double TONE_RMS_MAX_ERROR = 3.0;
    private static final double RMS_SMOOTHING_PARAM = 0.9;

    private static final double MAX_VAL = Math.pow(2, 15);

    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 static final int TEST_DURATION_DEFAULT_MS = 2000;
    private static final int TEST_DURATION_TONE_MS = TEST_DURATION_DEFAULT_MS;
    private static final int TEST_DURATION_NOISE_MS = TEST_DURATION_DEFAULT_MS;
    private static final int TEST_DURATION_USB_BACKGROUND_MS = TEST_DURATION_DEFAULT_MS;
    private static final int TEST_DURATION_USB_NOISE_MS = TEST_DURATION_DEFAULT_MS;

    private static final int BLOCK_SIZE_SAMPLES = 4096;
    private static final int SAMPLING_RATE = 48000;
    private static final int RECORD_SOURCE = MediaRecorder.AudioSource.VOICE_RECOGNITION;

    private static final int BANDS_MIC = 3;
    private static final int BANDS_TONE = 3;
    private static final int BANDS_BACKGROUND = 3;

    private int mCurrentTest = TEST_NONE;
    private boolean mTestsDone[] = new boolean[TEST_COUNT];
    final OnBtnClickListener mBtnClickListener = new OnBtnClickListener();

    private Button mButtonTestTone;
    private ProgressBar mProgressTone;
    private TextView mResultTestTone;
    private Button mButtonPlayTone;

    private Button mButtonTestNoise;
    private ProgressBar mProgressNoise;
    private TextView mResultTestNoise;
    private Button mButtonPlayNoise;

    private Button mButtonTestUsbBackground;
    private ProgressBar mProgressUsbBackground;
    private TextView mResultTestUsbBackground;

    private Button mButtonTestUsbNoise;
    private ProgressBar mProgressUsbNoise;
    private TextView mResultTestUsbNoise;
    private Button mButtonPlayUsbNoise;

    private TextView mGlobalResultText;

    private short[] mAudioShortArray2;

    private SoundPlayerObject mSPlayer;
    private SoundRecorderObject mSRecorder;

    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;

    private AudioBandSpecs[] mBandSpecsMic = new AudioBandSpecs[BANDS_MIC];
    private AudioBandSpecs[] mBandSpecsTone = new AudioBandSpecs[BANDS_TONE];
    private AudioBandSpecs[] mBandSpecsBack = new AudioBandSpecs[BANDS_BACKGROUND];
    private Results mResultsMic;
    private Results mResultsTone;
    private Results mResultsBack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.audio_frequency_voice_recognition_activity);

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

        mSRecorder = new SoundRecorderObject(SAMPLING_RATE, BLOCK_SIZE_SAMPLES,
                RECORD_SOURCE) {
            @Override
            public void periodicNotification(AudioRecord recorder) {

                int samplesAvailable = mPipe.availableToRead();
                int samplesNeeded = BLOCK_SIZE_SAMPLES;
                if (samplesAvailable >= samplesNeeded) {
                    mPipe.read(mAudioShortArray2, 0, samplesNeeded);

                    //compute
                    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;
                        }

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

                    double total_rms = rms * RMS_SMOOTHING_PARAM + mRMS * (1 - RMS_SMOOTHING_PARAM);
                    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[] magnitude = new double[BLOCK_SIZE_SAMPLES / 2];
                    for (i = 0; i < BLOCK_SIZE_SAMPLES / 2; i++) {
                        magnitude[i] = Math.sqrt(mC.mReal[i] * mC.mReal[i] +
                                mC.mImag[i] * mC.mImag[i]);
                    }

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

            @Override
            public void markerReached(AudioRecord track) {

            }
        };

        // Test tone
        mButtonTestTone = (Button) findViewById(R.id.vr_button_test_tone);
        mButtonTestTone.setOnClickListener(mBtnClickListener);
        mProgressTone = (ProgressBar) findViewById(R.id.vr_test_tone_progress_bar);
        mResultTestTone = (TextView) findViewById(R.id.vr_test_tone_result);
        mButtonPlayTone = (Button) findViewById(R.id.vr_button_play_tone);
        mButtonPlayTone.setOnClickListener(mBtnClickListener);
        showWait(mProgressTone, false);

        //Test Noise
        mButtonTestNoise = (Button) findViewById(R.id.vr_button_test_noise);
        mButtonTestNoise.setOnClickListener(mBtnClickListener);
        mProgressNoise = (ProgressBar) findViewById(R.id.vr_test_noise_progress_bar);
        mResultTestNoise = (TextView) findViewById(R.id.vr_test_noise_result);
        mButtonPlayNoise = (Button) findViewById(R.id.vr_button_play_noise);
        mButtonPlayNoise.setOnClickListener(mBtnClickListener);
        showWait(mProgressNoise, false);

        //USB Background
        mButtonTestUsbBackground = (Button) findViewById(R.id.vr_button_test_usb_background);
        mButtonTestUsbBackground.setOnClickListener(mBtnClickListener);
        mProgressUsbBackground = (ProgressBar)
                findViewById(R.id.vr_test_usb_background_progress_bar);
        mResultTestUsbBackground = (TextView)
                findViewById(R.id.vr_test_usb_background_result);
        showWait(mProgressUsbBackground, false);

        mButtonTestUsbNoise = (Button) findViewById(R.id.vr_button_test_usb_noise);
        mButtonTestUsbNoise.setOnClickListener(mBtnClickListener);
        mProgressUsbNoise = (ProgressBar)findViewById(R.id.vr_test_usb_noise_progress_bar);
        mResultTestUsbNoise = (TextView) findViewById(R.id.vr_test_usb_noise_result);
        mButtonPlayUsbNoise = (Button) findViewById(R.id.vr_button_play_usb_noise);
        mButtonPlayUsbNoise.setOnClickListener(mBtnClickListener);
        showWait(mProgressUsbNoise, false);

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

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

        int overlap = BLOCK_SIZE_SAMPLES / 2;

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

        setPassFailButtonClickListeners();
        getPassButton().setEnabled(false);
        setInfoResources(R.string.audio_frequency_voice_recognition_test,
                R.string.audio_frequency_voice_recognition_info, -1);

        //Init bands for Mic test
        mBandSpecsMic[0] = new AudioBandSpecs(
                30, 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, 4000,       /* frequency start,stop */
                6.0, -6.0,     /* start top,bottom value */
                6.0, -6.0      /* stop top,bottom value */);

        mBandSpecsMic[2] = new AudioBandSpecs(
                4000, 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 */);

        mResultsMic = new Results("mic_response", BANDS_MIC);
        mResultsTone = new Results("tone_response", BANDS_TONE);
        mResultsBack = new Results("background_response", BANDS_BACKGROUND);
        connectRefMicUI();
    }

    //
    // Overrides
    //
    void enableTestUI(boolean enable) {
        mButtonTestTone.setEnabled(enable);
        mButtonPlayTone.setEnabled(enable);

        mButtonTestNoise.setEnabled(enable);
        mButtonPlayNoise.setEnabled(enable);

        mButtonTestUsbBackground.setEnabled(enable);

        mButtonTestUsbNoise.setEnabled(enable);
        mButtonPlayUsbNoise.setEnabled(enable);
    }

    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();
            if (id == R.id.vr_button_test_tone) {
                startTest(TEST_TONE);
            } else if (id == R.id.vr_button_play_tone) {
                playerToggleButton(id, SOURCE_TONE);
            } else if (id == R.id.vr_button_test_noise) {
                startTest(TEST_NOISE);
            } else if (id == R.id.vr_button_play_noise) {
                playerToggleButton(id, SOURCE_NOISE);
            } else if (id == R.id.vr_button_test_usb_background) {
                startTest(TEST_USB_BACKGROUND);
            } else if (id == R.id.vr_button_test_usb_noise) {
                startTest(TEST_USB_NOISE);
            } else if (id == R.id.vr_button_play_usb_noise) {
                playerToggleButton(id, SOURCE_NOISE);
            }
        }
    }

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

        mButtonPlayTone.setText(playResId == R.id.vr_button_play_tone ? stop : play);
        mButtonPlayNoise.setText(playResId == R.id.vr_button_play_noise ? stop : play);
        mButtonPlayUsbNoise.setText(playResId ==
                R.id.vr_button_play_usb_noise ? stop : play);
    }

    private void playerSetSource(int sourceIndex) {
        switch (sourceIndex) {
            case SOURCE_TONE:
                mSPlayer.setSoundWithResId(mContext, R.raw.onekhztone);
                break;
            default:
            case SOURCE_NOISE:
                mSPlayer.setSoundWithResId(mContext,
                        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);
        }
    }

    private void showWait(ProgressBar pb, boolean show) {
        pb.setVisibility(show ? View.VISIBLE : 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 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) SAMPLING_RATE * i / (double) BLOCK_SIZE_SAMPLES;
            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
        double offset = anchorBand > -1 && anchorBand < bandCount ?
                results.mAverageEnergyPerBand[anchorBand] : 0;
        for (int b = 0; b < bandCount; b++) {
            bandsSpecs[b].setOffset(offset);
        }

        //test points in band.
        currentBand = 0;
        for (int i = 0; i < points; i++) {
            double freq = (double) SAMPLING_RATE * i / (double) BLOCK_SIZE_SAMPLES;
            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 written to it.
        //Currently, this data is always BLOCK_SIZE_SAMPLES/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]);

            //Use reference measurement to compensate for speaker response.
            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));
            //check that the spectrum is really a tone around 1 khz
            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");
            }
        }

        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");

        storeTestResults(mResultsTone);
        storeTestResults(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");

        getPassButton().setEnabled(allTestsPassed);
        return sb.toString();
    }

    Thread mTestThread;
    private void startTest(int testId) {
        if (mTestThread != null && mTestThread.isAlive()) {
            Log.v(TAG, "test Thread already running.");
            return;
        }
        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_MS);
                            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_MS);
                            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_MS);
                            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_MS);
                            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();
    }

    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(mContext);
        };
        public void record(int durationMs) {
            mSRecorder.startRecording();
            try {
                Thread.sleep(durationMs);
            } catch (InterruptedException e) {
                e.printStackTrace();
                //restore interrupted status
                Thread.currentThread().interrupt();
            }
            mSRecorder.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);
                    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;
        }
    }

    //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 storeTestResults(Results results) {
        String channelLabel = "channel_" + results.mLabel;

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

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

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

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

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

    @Override // PassFailButtons
    public void recordTestResults() {
        getReportLog().submit();
    }

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

    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);
    }

}
