// Path: app/src/main/java/ee/ioc/phon/android/speechutils/MediaFormatFactory.java
// public class MediaFormatFactory {
// 
//     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
//     public static MediaFormat createMediaFormat(String mime, int sampleRate) {
//         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//             MediaFormat format = new MediaFormat();
//             // TODO: this causes a crash in MediaCodec.configure
//             //format.setString(MediaFormat.KEY_FRAME_RATE, null);
//             format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
//             format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
//             format.setString(MediaFormat.KEY_MIME, mime);
//             if ("audio/mp4a-latm".equals(mime)) {
//                 format.setInteger(MediaFormat.KEY_AAC_PROFILE, 2); // TODO: or 39?
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
//             } else if ("audio/flac".equals(mime)) {
//                 //format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC); // API=21
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
//                 //TODO: use another bit rate, does not seem to have effect always
//                 //format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
//                 // TODO: experiment with 0 (fastest/least) to 8 (slowest/most)
//                 //format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 0);
//             } else if ("audio/opus".equals(mime)) {
//                 //format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_OPUS); // API=21
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
//             } else {
//                 // TODO: assuming: "audio/amr-wb"
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 23050);
//             }
//             return format;
//         }
//         return null;
//     }
// 
//     //final int kAACProfiles[] = {
//     //        2 /* OMX_AUDIO_AACObjectLC */,
//     //        5 /* OMX_AUDIO_AACObjectHE */,
//     //        39 /* OMX_AUDIO_AACObjectELD */
//     //};
// 
//     //if (kAACProfiles[k] == 5 && kSampleRates[i] < 22050) {
//     //    // Is this right? HE does not support sample rates < 22050Hz?
//     //    continue;
//     //}
//     // final int kSampleRates[] = {8000, 11025, 22050, 44100, 48000};
//     // final int kBitRates[] = {64000, 128000};
// }


import android.annotation.TargetApi;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.os.Build;
import android.text.TextUtils;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import ee.ioc.phon.android.speechutils.Log;
import ee.ioc.phon.android.speechutils.MediaFormatFactory;
        header[30] = (byte) ((byteRate >> 16) & 0xff);
        header[31] = (byte) ((byteRate >> 24) & 0xff);
        header[32] = (byte) (2 * 16 / 8);  // block align
        header[33] = 0;
        header[34] = (byte) (8 * resolutionInBytes);  // bits per sample
        header[35] = 0;
        header[36] = 'd';
        header[37] = 'a';
        header[38] = 't';
        header[39] = 'a';
        header[40] = (byte) (totalAudioLen & 0xff);
        header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
        header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
        header[43] = (byte) ((totalAudioLen >> 24) & 0xff);

        return header;
    }

    public static byte[] getRecordingAsWav(byte[] pcm, int sampleRate, short resolutionInBytes, short channels) {
        byte[] header = getWavHeader(pcm.length, sampleRate, resolutionInBytes, channels);
        byte[] wav = new byte[header.length + pcm.length];
        System.arraycopy(header, 0, wav, 0, header.length);
        System.arraycopy(pcm, 0, wav, header.length, pcm.length);
        return wav;
    }

    // TODO: use MediaFormat.MIMETYPE_AUDIO_FLAC) on API>=21
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static List<String> getAvailableEncoders(String mime, int sampleRate) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Path: app/src/main/java/ee/ioc/phon/android/speechutils/MediaFormatFactory.java
// public class MediaFormatFactory {
// 
//     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
//     public static MediaFormat createMediaFormat(String mime, int sampleRate) {
//         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//             MediaFormat format = new MediaFormat();
//             // TODO: this causes a crash in MediaCodec.configure
//             //format.setString(MediaFormat.KEY_FRAME_RATE, null);
//             format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
//             format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
//             format.setString(MediaFormat.KEY_MIME, mime);
//             if ("audio/mp4a-latm".equals(mime)) {
//                 format.setInteger(MediaFormat.KEY_AAC_PROFILE, 2); // TODO: or 39?
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
//             } else if ("audio/flac".equals(mime)) {
//                 //format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC); // API=21
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
//                 //TODO: use another bit rate, does not seem to have effect always
//                 //format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
//                 // TODO: experiment with 0 (fastest/least) to 8 (slowest/most)
//                 //format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 0);
//             } else if ("audio/opus".equals(mime)) {
//                 //format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_OPUS); // API=21
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
//             } else {
//                 // TODO: assuming: "audio/amr-wb"
//                 format.setInteger(MediaFormat.KEY_BIT_RATE, 23050);
//             }
//             return format;
//         }
//         return null;
//     }
// 
//     //final int kAACProfiles[] = {
//     //        2 /* OMX_AUDIO_AACObjectLC */,
//     //        5 /* OMX_AUDIO_AACObjectHE */,
//     //        39 /* OMX_AUDIO_AACObjectELD */
//     //};
// 
//     //if (kAACProfiles[k] == 5 && kSampleRates[i] < 22050) {
//     //    // Is this right? HE does not support sample rates < 22050Hz?
//     //    continue;
//     //}
//     // final int kSampleRates[] = {8000, 11025, 22050, 44100, 48000};
//     // final int kBitRates[] = {64000, 128000};
// }


// Path: app/src/main/java/ee/ioc/phon/android/speechutils/utils/AudioUtils.java
import android.annotation.TargetApi;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.os.Build;
import android.text.TextUtils;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import ee.ioc.phon.android.speechutils.Log;
import ee.ioc.phon.android.speechutils.MediaFormatFactory;

        header[30] = (byte) ((byteRate >> 16) & 0xff);
        header[31] = (byte) ((byteRate >> 24) & 0xff);
        header[32] = (byte) (2 * 16 / 8);  // block align
        header[33] = 0;
        header[34] = (byte) (8 * resolutionInBytes);  // bits per sample
        header[35] = 0;
        header[36] = 'd';
        header[37] = 'a';
        header[38] = 't';
        header[39] = 'a';
        header[40] = (byte) (totalAudioLen & 0xff);
        header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
        header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
        header[43] = (byte) ((totalAudioLen >> 24) & 0xff);

        return header;
    }

    public static byte[] getRecordingAsWav(byte[] pcm, int sampleRate, short resolutionInBytes, short channels) {
        byte[] header = getWavHeader(pcm.length, sampleRate, resolutionInBytes, channels);
        byte[] wav = new byte[header.length + pcm.length];
        System.arraycopy(header, 0, wav, 0, header.length);
        System.arraycopy(pcm, 0, wav, header.length, pcm.length);
        return wav;
    }

    // TODO: use MediaFormat.MIMETYPE_AUDIO_FLAC) on API>=21
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static List<String> getAvailableEncoders(String mime, int sampleRate) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            MediaFormat format = MediaFormatFactory.createMediaFormat(mime, sampleRate);