|
|
|
|
@ -87,9 +87,13 @@ public final class ProbeActivity extends Activity {
|
|
|
|
|
int channels = getIntent().getIntExtra("channels", 0); |
|
|
|
|
if (api == null || api.equals("track")) trial("track-mono", 0, 1); |
|
|
|
|
if (api == null || api.equals("aaudio")) { |
|
|
|
|
String sharing = getIntent().getStringExtra("sharing"); |
|
|
|
|
for (int c : new int[]{1, 2}) { |
|
|
|
|
if (channels != 0 && channels != c) continue; |
|
|
|
|
for (int mode : new int[]{1, 2}) trial("aaudio-" + (mode == 1 ? "shared" : "exclusive") + "-ch" + c, mode, c); |
|
|
|
|
for (int mode : new int[]{1, 2}) { |
|
|
|
|
String name = mode == 1 ? "shared" : "exclusive"; |
|
|
|
|
if (sharing == null || sharing.equals(name)) trial("aaudio-" + name + "-ch" + c, mode, c); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
show("probe complete captured=" + captured.get() + " captureError=" + captureError.get() + " cancelled=" + cancelled); |
|
|
|
|
@ -156,7 +160,16 @@ public final class ProbeActivity extends Activity {
|
|
|
|
|
route(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE); |
|
|
|
|
measure(output, name + "/earpiece-existing"); |
|
|
|
|
} |
|
|
|
|
if (!cancelled) try (Output output = open(mode, channels)) { measure(output, name + "/earpiece-new"); } |
|
|
|
|
if (!cancelled) try (Output output = open(mode, channels)) { |
|
|
|
|
measure(output, name + "/earpiece-new"); |
|
|
|
|
if (getIntent().getBooleanExtra("roundtrip", false)) { |
|
|
|
|
route(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); |
|
|
|
|
measure(output, name + "/speaker-existing"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!cancelled && getIntent().getBooleanExtra("roundtrip", false)) { |
|
|
|
|
try (Output output = open(mode, channels)) { measure(output, name + "/speaker-reopened"); } |
|
|
|
|
} |
|
|
|
|
} catch (RuntimeException e) { Log.e(TAG, "trial failed name=" + name, e); } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -213,10 +226,17 @@ public final class ProbeActivity extends Activity {
|
|
|
|
|
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO).build()) |
|
|
|
|
.setBufferSizeInBytes(Math.max(min * 2, 3840)).setTransferMode(AudioTrack.MODE_STREAM) |
|
|
|
|
.setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY).build(); |
|
|
|
|
int actual = track.setBufferSizeInFrames(960); |
|
|
|
|
if (Build.VERSION.SDK_INT >= 31) track.setStartThresholdInFrames(actual); |
|
|
|
|
Log.i(TAG, "track opened requested=1 performance=" + track.getPerformanceMode() + " buffer=" + actual); |
|
|
|
|
track.play(); |
|
|
|
|
try { |
|
|
|
|
if (track.getState() != AudioTrack.STATE_INITIALIZED) throw new IllegalStateException("track not initialized"); |
|
|
|
|
int bufferMs = getIntent().getIntExtra("buffer_ms", 20); |
|
|
|
|
if (bufferMs != 20 && bufferMs != 40) throw new IllegalArgumentException("buffer_ms must be 20 or 40"); |
|
|
|
|
int actual = track.setBufferSizeInFrames(48 * bufferMs); |
|
|
|
|
if (actual <= 0) throw new IllegalStateException("track buffer result=" + actual); |
|
|
|
|
if (Build.VERSION.SDK_INT >= 31 && track.setStartThresholdInFrames(actual) <= 0) |
|
|
|
|
throw new IllegalStateException("track start threshold rejected"); |
|
|
|
|
Log.i(TAG, "track opened requested=1 performance=" + track.getPerformanceMode() + " buffer=" + actual); |
|
|
|
|
track.play(); |
|
|
|
|
} catch (RuntimeException e) { track.release(); throw e; } |
|
|
|
|
writer = new Thread(() -> { |
|
|
|
|
short[] silence = new short[960]; |
|
|
|
|
while (running && !cancelled) { |
|
|
|
|
|