Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4aa865bf authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Mic and Internal audio recording mismatch" into sc-v2-dev am: 61404e67 am: d708d483

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15482616

Change-Id: Ib3bc613480e7e6dd04770de304b8c02813b4b2dc
parents c2a7ee19 d708d483
Loading
Loading
Loading
Loading
+67 −41
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.media.MediaMuxer;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.util.Log;
import android.util.MathUtils;

import java.io.IOException;
import java.nio.ByteBuffer;
@@ -128,30 +129,64 @@ public class ScreenInternalAudioRecorder {
        mThread = new Thread(() -> {
            short[] bufferInternal = null;
            short[] bufferMic = null;
            byte[] buffer = null;
            byte[] buffer = new byte[size];

            if (mMic) {
                bufferInternal = new short[size / 2];
                bufferMic = new short[size / 2];
            } else {
                buffer = new byte[size];
            }

            while (true) {
            int readBytes = 0;
            int readShortsInternal = 0;
            int offsetShortsInternal = 0;
            int readShortsMic = 0;
            int offsetShortsMic = 0;
            while (true) {
                if (mMic) {
                    readShortsInternal = mAudioRecord.read(bufferInternal, 0,
                            bufferInternal.length);
                    readShortsMic = mAudioRecordMic.read(bufferMic, 0, bufferMic.length);
                    readShortsInternal = mAudioRecord.read(bufferInternal, offsetShortsInternal,
                            bufferInternal.length - offsetShortsInternal);
                    readShortsMic = mAudioRecordMic.read(
                            bufferMic, offsetShortsMic, bufferMic.length - offsetShortsMic);

                    // if both error, end the recording
                    if (readShortsInternal < 0 && readShortsMic < 0) {
                        break;
                    }

                    // if one has an errors, fill its buffer with zeros and assume it is mute
                    // with the same size as the other buffer
                    if (readShortsInternal < 0) {
                        readShortsInternal = readShortsMic;
                        offsetShortsInternal = offsetShortsMic;
                        java.util.Arrays.fill(bufferInternal, (short) 0);
                    }

                    if (readShortsMic < 0) {
                        readShortsMic = readShortsInternal;
                        offsetShortsMic = offsetShortsInternal;
                        java.util.Arrays.fill(bufferMic, (short) 0);
                    }

                    // Add offset (previous unmixed values) to the buffer
                    readShortsInternal += offsetShortsInternal;
                    readShortsMic += offsetShortsMic;

                    int minShorts = Math.min(readShortsInternal, readShortsMic);
                    readBytes = minShorts * 2;

                    // modify the volume
                    bufferMic = scaleValues(bufferMic,
                            readShortsMic, MIC_VOLUME_SCALE);
                    readBytes = Math.min(readShortsInternal, readShortsMic) * 2;
                    buffer = addAndConvertBuffers(bufferInternal, readShortsInternal, bufferMic,
                            readShortsMic);
                    // scale only mixed shorts
                    scaleValues(bufferMic, minShorts, MIC_VOLUME_SCALE);
                    // Mix the two buffers
                    addAndConvertBuffers(bufferInternal, bufferMic, buffer, minShorts);

                    // shift unmixed shorts to the beginning of the buffer
                    shiftToStart(bufferInternal, minShorts, offsetShortsInternal);
                    shiftToStart(bufferMic, minShorts, offsetShortsMic);

                    // reset the offset for the next loop
                    offsetShortsInternal = readShortsInternal - minShorts;
                    offsetShortsMic = readShortsMic - minShorts;
                } else {
                    readBytes = mAudioRecord.read(buffer, 0, buffer.length);
                }
@@ -169,40 +204,31 @@ public class ScreenInternalAudioRecorder {
        });
    }

    private short[] scaleValues(short[] buff, int len, float scale) {
        for (int i = 0; i < len; i++) {
            int oldValue = buff[i];
            int newValue = (int) (buff[i] * scale);
            if (newValue > Short.MAX_VALUE) {
                newValue = Short.MAX_VALUE;
            } else if (newValue < Short.MIN_VALUE) {
                newValue = Short.MIN_VALUE;
    /**
     * moves all bits from start to end to the beginning of the array
     */
    private void shiftToStart(short[] target, int start, int end) {
        for (int i = 0; i  < end - start; i++) {
            target[i] = target[start + i];
        }
            buff[i] = (short) (newValue);
    }
        return buff;

    private void scaleValues(short[] buff, int len, float scale) {
        for (int i = 0; i < len; i++) {
            int newValue = (int) (buff[i] * scale);
            buff[i] = (short) MathUtils.constrain(newValue, Short.MIN_VALUE, Short.MAX_VALUE);
        }
    private byte[] addAndConvertBuffers(short[] a1, int a1Limit, short[] a2, int a2Limit) {
        int size = Math.max(a1Limit, a2Limit);
        if (size < 0) return new byte[0];
        byte[] buff = new byte[size * 2];
        for (int i = 0; i < size; i++) {
            int sum;
            if (i > a1Limit) {
                sum = a2[i];
            } else if (i > a2Limit) {
                sum = a1[i];
            } else {
                sum = (int) a1[i] + (int) a2[i];
    }

            if (sum > Short.MAX_VALUE) sum = Short.MAX_VALUE;
            if (sum < Short.MIN_VALUE) sum = Short.MIN_VALUE;
    private void addAndConvertBuffers(short[] src1, short[] src2, byte[] dst, int sizeShorts) {
        for (int i = 0; i < sizeShorts; i++) {
            int sum;
            sum = (short) MathUtils.constrain(
                    (int) src1[i] + (int) src2[i], Short.MIN_VALUE, Short.MAX_VALUE);
            int byteIndex = i * 2;
            buff[byteIndex] = (byte) (sum & 0xff);
            buff[byteIndex + 1] = (byte) ((sum >> 8) & 0xff);
            dst[byteIndex] = (byte) (sum & 0xff);
            dst[byteIndex + 1] = (byte) ((sum >> 8) & 0xff);
        }
        return buff;
    }

    private void encode(byte[] buffer, int readBytes) {