diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java | 108 |
1 files changed, 67 insertions, 41 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java index 0aa9d4d662a5..5a6f2a2a912d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java @@ -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]; } + int readBytes = 0; + int readShortsInternal = 0; + int offsetShortsInternal = 0; + int readShortsMic = 0; + int offsetShortsMic = 0; while (true) { - int readBytes = 0; - int readShortsInternal = 0; - int readShortsMic = 0; 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) { + /** + * 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]; + } + } + + private void 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; - } - buff[i] = (short) (newValue); + buff[i] = (short) MathUtils.constrain(newValue, Short.MIN_VALUE, Short.MAX_VALUE); } - return buff; } - 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) { |