Fix voice message waveform only showing activity at the beginning.

Co-authored-by: Greyson Parrelli <greyson@signal.org>
This commit is contained in:
Alex Hart
2026-03-13 13:48:33 -03:00
committed by Michelle Tang
parent 380036195a
commit eaa1124e71

View File

@@ -23,7 +23,6 @@ public final class AudioWaveFormGenerator {
private static final String TAG = Log.tag(AudioWaveFormGenerator.class); private static final String TAG = Log.tag(AudioWaveFormGenerator.class);
public static final int BAR_COUNT = 46; public static final int BAR_COUNT = 46;
private static final int SAMPLES_PER_BAR = 4;
private AudioWaveFormGenerator() {} private AudioWaveFormGenerator() {}
@@ -70,42 +69,35 @@ public final class AudioWaveFormGenerator {
long kTimeOutUs = 5000; long kTimeOutUs = 5000;
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
boolean sawInputEOS = false; boolean extractorDone = false;
boolean inputEOSQueued = false;
boolean sawOutputEOS = false; boolean sawOutputEOS = false;
int noOutputCounter = 0; int noOutputCounter = 0;
int maxSamplesPerBar = Math.max(1, (int) (totalDurationUs / BAR_COUNT / 10_000));
boolean[] barSufficientlySampled = new boolean[BAR_COUNT];
while (!sawOutputEOS && noOutputCounter < 50) { while (!sawOutputEOS && noOutputCounter < 50) {
noOutputCounter++; noOutputCounter++;
if (!sawInputEOS) { if (!inputEOSQueued) {
int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs); int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
if (inputBufIndex >= 0) { if (inputBufIndex >= 0) {
if (extractorDone) {
codec.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
inputEOSQueued = true;
} else {
ByteBuffer dstBuf = codec.getInputBuffer(inputBufIndex); ByteBuffer dstBuf = codec.getInputBuffer(inputBufIndex);
int sampleSize = extractor.readSampleData(dstBuf, 0); int sampleSize = extractor.readSampleData(dstBuf, 0);
long presentationTimeUs = 0; long presentationTimeUs = 0;
if (sampleSize < 0) { if (sampleSize < 0) {
sawInputEOS = true; codec.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
sampleSize = 0; inputEOSQueued = true;
} else { } else {
presentationTimeUs = extractor.getSampleTime(); presentationTimeUs = extractor.getSampleTime();
}
codec.queueInputBuffer( codec.queueInputBuffer(inputBufIndex, 0, sampleSize, presentationTimeUs, 0);
inputBufIndex,
0,
sampleSize,
presentationTimeUs,
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS) { extractorDone = !extractor.advance();
int barSampleIndex = (int) (SAMPLES_PER_BAR * (wave.length * extractor.getSampleTime()) / totalDurationUs);
sawInputEOS = !extractor.advance();
int nextBarSampleIndex = (int) (SAMPLES_PER_BAR * (wave.length * extractor.getSampleTime()) / totalDurationUs);
while (!sawInputEOS && nextBarSampleIndex == barSampleIndex) {
sawInputEOS = !extractor.advance();
if (!sawInputEOS) {
nextBarSampleIndex = (int) (SAMPLES_PER_BAR * (wave.length * extractor.getSampleTime()) / totalDurationUs);
}
} }
} }
} }
@@ -119,16 +111,19 @@ public final class AudioWaveFormGenerator {
noOutputCounter = 0; noOutputCounter = 0;
} }
ByteBuffer buf = codec.getOutputBuffer(outputBufferIndex);
int barIndex = (int) ((wave.length * info.presentationTimeUs) / totalDurationUs); int barIndex = (int) ((wave.length * info.presentationTimeUs) / totalDurationUs);
if (barIndex >= 0 && barIndex < wave.length && !barSufficientlySampled[barIndex]) {
ByteBuffer buf = codec.getOutputBuffer(outputBufferIndex);
long total = 0; long total = 0;
for (int i = 0; i < info.size; i += 2 * 4) { for (int i = 0; i < info.size; i += 2 * 4) {
short aShort = buf.getShort(i); short aShort = buf.getShort(i);
total += Math.abs(aShort); total += Math.abs(aShort);
} }
if (barIndex >= 0 && barIndex < wave.length) {
wave[barIndex] += total; wave[barIndex] += total;
waveSamples[barIndex] += info.size / 2; waveSamples[barIndex] += info.size / 2;
if (waveSamples[barIndex] >= maxSamplesPerBar) {
barSufficientlySampled[barIndex] = true;
}
} }
codec.releaseOutputBuffer(outputBufferIndex, false); codec.releaseOutputBuffer(outputBufferIndex, false);
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {