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

@@ -22,8 +22,7 @@ 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() {}
@@ -68,44 +67,37 @@ public final class AudioWaveFormGenerator {
extractor.selectTrack(0); extractor.selectTrack(0);
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 sawOutputEOS = false; boolean inputEOSQueued = false;
int noOutputCounter = 0; boolean sawOutputEOS = false;
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) {
ByteBuffer dstBuf = codec.getInputBuffer(inputBufIndex); if (extractorDone) {
int sampleSize = extractor.readSampleData(dstBuf, 0); codec.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
long presentationTimeUs = 0; inputEOSQueued = true;
if (sampleSize < 0) {
sawInputEOS = true;
sampleSize = 0;
} else { } else {
presentationTimeUs = extractor.getSampleTime(); ByteBuffer dstBuf = codec.getInputBuffer(inputBufIndex);
} int sampleSize = extractor.readSampleData(dstBuf, 0);
long presentationTimeUs = 0;
codec.queueInputBuffer( if (sampleSize < 0) {
inputBufIndex, codec.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
0, inputEOSQueued = true;
sampleSize, } else {
presentationTimeUs, presentationTimeUs = extractor.getSampleTime();
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS) { codec.queueInputBuffer(inputBufIndex, 0, sampleSize, presentationTimeUs, 0);
int barSampleIndex = (int) (SAMPLES_PER_BAR * (wave.length * extractor.getSampleTime()) / totalDurationUs);
sawInputEOS = !extractor.advance(); extractorDone = !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);
long total = 0; if (barIndex >= 0 && barIndex < wave.length && !barSufficientlySampled[barIndex]) {
for (int i = 0; i < info.size; i += 2 * 4) { ByteBuffer buf = codec.getOutputBuffer(outputBufferIndex);
short aShort = buf.getShort(i); long total = 0;
total += Math.abs(aShort); for (int i = 0; i < info.size; i += 2 * 4) {
} short aShort = buf.getShort(i);
if (barIndex >= 0 && barIndex < wave.length) { total += Math.abs(aShort);
}
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) {