Loading packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java +67 −41 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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) { Loading Loading
packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java +67 −41 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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) { Loading