discord-jadx/app/src/main/java/co/discord/media_engine/SoundshareAudioSource.java

249 lines
10 KiB
Java

package co.discord.media_engine;
import android.media.AudioRecord;
import android.os.Process;
import android.util.Log;
import b.d.b.a.a;
import com.discord.models.domain.ModelAuditLogEntry;
import d0.z.d.m;
import java.nio.ByteBuffer;
import kotlin.jvm.internal.DefaultConstructorMarker;
import org.webrtc.ThreadUtils;
import org.webrtc.TimestampAligner;
/* compiled from: SoundshareAudioSource.kt */
/* loaded from: classes.dex */
public final class SoundshareAudioSource {
private static final long AUDIO_RECORD_THREAD_JOIN_TIMEOUT_MS = 2000;
private static final int BITS_PER_SAMPLE = 16;
private static final int BUFFERS_PER_SECOND = 100;
private static final int BUFFER_SIZE_FACTOR = 2;
private static final int CALLBACK_BUFFER_SIZE_MS = 10;
public static final Companion Companion = new Companion(null);
private static final String TAG = "SoundshareAudioSource";
private static volatile boolean microphoneMute;
private AudioRecord audioRecord;
private AudioRecordThread audioThread;
private ByteBuffer byteBuffer;
private final long nativeInstance = nativeCreateInstance();
private boolean released;
/* compiled from: SoundshareAudioSource.kt */
/* loaded from: classes.dex */
public final class AudioRecordThread extends Thread {
private final AudioRecord audioRecord;
private final ByteBuffer byteBuffer;
private final byte[] emptyBytes;
private volatile boolean keepAlive = true;
public final /* synthetic */ SoundshareAudioSource this$0;
private long timestamp;
/* JADX WARN: 'super' call moved to the top of the method (can break code semantics) */
public AudioRecordThread(SoundshareAudioSource soundshareAudioSource, String str, AudioRecord audioRecord, ByteBuffer byteBuffer, long j) {
super(str);
m.checkNotNullParameter(str, ModelAuditLogEntry.CHANGE_KEY_NAME);
m.checkNotNullParameter(audioRecord, "audioRecord");
m.checkNotNullParameter(byteBuffer, "byteBuffer");
this.this$0 = soundshareAudioSource;
this.audioRecord = audioRecord;
this.byteBuffer = byteBuffer;
this.timestamp = j;
this.emptyBytes = new byte[byteBuffer.capacity()];
}
@Override // java.lang.Thread, java.lang.Runnable
public void run() {
Process.setThreadPriority(-19);
Companion.access$assertTrue(SoundshareAudioSource.Companion, this.audioRecord.getRecordingState() == 3);
while (this.keepAlive) {
AudioRecord audioRecord = this.audioRecord;
ByteBuffer byteBuffer = this.byteBuffer;
int read = audioRecord.read(byteBuffer, byteBuffer.capacity());
this.timestamp = TimestampAligner.getRtcTimeNanos();
if (read == this.byteBuffer.capacity()) {
if (SoundshareAudioSource.access$getMicrophoneMute$cp()) {
this.byteBuffer.clear();
this.byteBuffer.put(this.emptyBytes);
}
if (this.keepAlive) {
SoundshareAudioSource.access$dataIsRecorded(this.this$0, read, this.timestamp);
}
} else {
String str = "AudioRecord.read failed: " + read;
Log.e(SoundshareAudioSource.TAG, str);
if (read == -3) {
this.keepAlive = false;
SoundshareAudioSource.access$reportSoundshareAudioSourceError(this.this$0, str);
}
}
}
try {
this.audioRecord.stop();
} catch (IllegalStateException e) {
StringBuilder R = a.R("AudioRecord.stop failed: ");
R.append(e.getMessage());
Log.e(SoundshareAudioSource.TAG, R.toString());
}
}
public final void stopThread() {
this.keepAlive = false;
}
}
/* compiled from: SoundshareAudioSource.kt */
/* loaded from: classes.dex */
public static final class Companion {
private Companion() {
}
public /* synthetic */ Companion(DefaultConstructorMarker defaultConstructorMarker) {
this();
}
public static final /* synthetic */ void access$assertTrue(Companion companion, boolean z2) {
companion.assertTrue(z2);
}
private final void assertTrue(boolean z2) {
if (!z2) {
throw new AssertionError("Expected condition to be true");
}
}
public final void setMicrophoneMute(boolean z2) {
Log.w(SoundshareAudioSource.TAG, "setMicrophoneMute(" + z2 + ')');
SoundshareAudioSource.access$setMicrophoneMute$cp(z2);
}
}
public static final /* synthetic */ void access$dataIsRecorded(SoundshareAudioSource soundshareAudioSource, int i, long j) {
soundshareAudioSource.dataIsRecorded(i, j);
}
public static final /* synthetic */ boolean access$getMicrophoneMute$cp() {
return microphoneMute;
}
public static final /* synthetic */ void access$reportSoundshareAudioSourceError(SoundshareAudioSource soundshareAudioSource, String str) {
soundshareAudioSource.reportSoundshareAudioSourceError(str);
}
public static final /* synthetic */ void access$setMicrophoneMute$cp(boolean z2) {
microphoneMute = z2;
}
private final int channelCountToConfiguration(int i) {
return i == 1 ? 16 : 12;
}
private final synchronized void dataIsRecorded(int i, long j) {
if (!this.released) {
nativeDataIsRecorded(this.nativeInstance, i, j);
}
}
private final native synchronized void nativeCacheDirectBufferAddress(long j, ByteBuffer byteBuffer);
private final native synchronized long nativeCreateInstance();
private final native void nativeDataIsRecorded(long j, int i, long j2);
private final native synchronized void nativeDestroyInstance(long j);
private final native void nativeSetSampleFormat(long j, int i, int i2, int i3);
private final void reportSoundshareAudioSourceError(String str) {
Log.e(TAG, "Run-time recording error: " + str);
}
private final void reportSoundshareAudioSourceInitError(String str) {
Log.e(TAG, "Init recording error: " + str);
}
private final void reportSoundshareAudioSourceStartError(String str) {
Log.e(TAG, "Start recording error: " + str);
}
public final long getNativeInstance() {
return this.nativeInstance;
}
public final synchronized void release() {
if (!this.released) {
AudioRecord audioRecord = this.audioRecord;
if (audioRecord != null) {
audioRecord.release();
}
this.audioRecord = null;
nativeDestroyInstance(this.nativeInstance);
this.released = true;
}
}
public final void setSampleFormat(int i, int i2, int i3) {
nativeSetSampleFormat(this.nativeInstance, i, i2, i3);
}
public final boolean startRecording(AudioRecord audioRecord) {
m.checkNotNullParameter(audioRecord, "audioRecord");
int channelCount = audioRecord.getChannelCount();
int sampleRate = audioRecord.getSampleRate();
if (this.audioRecord != null) {
reportSoundshareAudioSourceInitError("StartRecording called twice without StopRecording.");
return false;
}
this.audioRecord = audioRecord;
setSampleFormat(sampleRate, 16, channelCount);
ByteBuffer allocateDirect = ByteBuffer.allocateDirect((sampleRate / 100) * channelCount * 2);
this.byteBuffer = allocateDirect;
nativeCacheDirectBufferAddress(this.nativeInstance, allocateDirect);
int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelCountToConfiguration(channelCount), 2);
if (minBufferSize == -1 || minBufferSize == -2) {
reportSoundshareAudioSourceInitError(a.p("AudioRecord.getMinBufferSize failed: ", minBufferSize));
return false;
}
Math.max(minBufferSize * 2, allocateDirect.capacity());
if (audioRecord.getState() != 1) {
reportSoundshareAudioSourceInitError("Failed to create a new AudioRecord instance");
release();
return false;
}
try {
Companion.access$assertTrue(Companion, this.audioThread == null);
long rtcTimeNanos = TimestampAligner.getRtcTimeNanos();
try {
audioRecord.startRecording();
if (audioRecord.getRecordingState() != 3) {
reportSoundshareAudioSourceStartError("AudioRecord.startRecording failed - incorrect state :" + audioRecord.getRecordingState());
return false;
}
m.checkNotNullExpressionValue(allocateDirect, "byteBuffer");
AudioRecordThread audioRecordThread = new AudioRecordThread(this, "SoundshareThread", audioRecord, allocateDirect, rtcTimeNanos);
this.audioThread = audioRecordThread;
m.checkNotNull(audioRecordThread);
audioRecordThread.start();
return true;
} catch (IllegalStateException e) {
reportSoundshareAudioSourceStartError("AudioRecord.startRecording failed: " + e.getMessage());
return false;
}
} catch (Throwable th) {
Log.e(TAG, "SoundshareAudioSource.startRecording fail hard!", th);
throw th;
}
}
public final boolean stopRecording() {
AudioRecordThread audioRecordThread = this.audioThread;
if (audioRecordThread == null) {
return false;
}
audioRecordThread.stopThread();
if (!ThreadUtils.joinUninterruptibly(audioRecordThread, AUDIO_RECORD_THREAD_JOIN_TIMEOUT_MS)) {
Log.e(TAG, "Join of SoundshareThread timed out");
}
this.audioThread = null;
return true;
}
}