From ec08db458e6cedcb79a42f10eaac7f8da7e7bcdb Mon Sep 17 00:00:00 2001 From: christosts Date: Tue, 21 Nov 2023 07:36:48 -0800 Subject: [PATCH] MidiExtractor: mark only the first sample as key-frame This change fixes a bug with seeking forward in MIDI. When seeking forward, the progressive media period attempts to seek within the sample queue, if a key-frame exists before the seeking position. With MIDI, however, we can only skip Note-On and Note-Off samples and all other samples must be sent to the MIDI decoder. When seeking outside the sample queue, the MidiExtractor already instructs the player to start from the beginning of the MIDI input. With this change, only the first output sample is a key-frame, thus the progressive media period can no longer seek within the sample queue and is forced to seek from the MIDI input start always. Issue: androidx/media#704 #minor-release PiperOrigin-RevId: 584321443 --- RELEASENOTES.md | 2 + .../media3/decoder/midi/MidiExtractor.java | 88 ++++++-- .../media3/decoder/midi/TrackChunk.java | 20 +- .../media3/decoder/midi/TrackChunkTest.java | 4 +- .../extractordumps/midi/Twinkle.mid.0.dump | 190 +++++++++--------- .../midi/Twinkle.mid.unknown_length.dump | 190 +++++++++--------- .../mid_note_tempo_changes_simple.mid.dump | 36 ++-- .../midi/multi_note_tempo_changes.mid.dump | 60 +++--- .../seek_test_with_non_note_events.mid.dump | 44 ++-- 9 files changed, 340 insertions(+), 294 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 99aa703ab5..32ade8267d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -91,6 +91,8 @@ * Decoder Extensions (FFmpeg, VP9, AV1, MIDI, etc.): * MIDI decoder: Ignore SysEx event messages ([#710](https://github.com/androidx/media/pull/710)). + * MIDI: Fix issue where seeking forward skips the Program Change events + ([#704](https://github.com/androidx/media/issues/704). * Leanback extension: * Cast Extension: * Sanitize creation of a `Timeline` to not crash the app when loading diff --git a/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/MidiExtractor.java b/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/MidiExtractor.java index 088c481c7a..3e895d2b05 100644 --- a/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/MidiExtractor.java +++ b/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/MidiExtractor.java @@ -17,17 +17,19 @@ package androidx.media3.decoder.midi; import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkState; +import static androidx.media3.common.util.Assertions.checkStateNotNull; import static java.lang.annotation.ElementType.TYPE_USE; import androidx.annotation.IntDef; +import androidx.annotation.Nullable; import androidx.media3.common.C; +import androidx.media3.common.DataReader; import androidx.media3.common.Format; import androidx.media3.common.MimeTypes; import androidx.media3.common.ParserException; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; -import androidx.media3.extractor.DummyTrackOutput; import androidx.media3.extractor.Extractor; import androidx.media3.extractor.ExtractorInput; import androidx.media3.extractor.ExtractorOutput; @@ -43,6 +45,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.ArrayList; import java.util.PriorityQueue; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** Extracts data from MIDI containers. */ @UnstableApi @@ -99,14 +102,13 @@ public final class MidiExtractor implements Extractor, SeekMap { private int ticksPerQuarterNote; private long currentTimestampUs; private long startTimeUs; - private TrackOutput trackOutput; + private @MonotonicNonNull SingleKeyFrameTrackOutput trackOutput; public MidiExtractor() { state = STATE_INITIALIZED; trackChunkList = new ArrayList<>(); trackPriorityQueue = new PriorityQueue<>(); midiFileData = new ParsableByteArray(/* limit= */ 512); - trackOutput = new DummyTrackOutput(); } // Extractor implementation. @@ -117,7 +119,7 @@ public final class MidiExtractor implements Extractor, SeekMap { throw new IllegalStateException(); } - trackOutput = output.track(0, C.TRACK_TYPE_AUDIO); + trackOutput = new SingleKeyFrameTrackOutput(output.track(0, C.TRACK_TYPE_AUDIO)); trackOutput.format( new Format.Builder() .setCodecs(MimeTypes.AUDIO_MIDI) @@ -140,6 +142,9 @@ public final class MidiExtractor implements Extractor, SeekMap { public void seek(long position, long timeUs) { checkState(state != STATE_RELEASED); startTimeUs = timeUs; + if (trackOutput != null) { + trackOutput.reset(); + } if (state == STATE_LOADING) { midiFileData.setPosition(0); bytesRead = 0; @@ -211,7 +216,8 @@ public final class MidiExtractor implements Extractor, SeekMap { outputEmptySample(); } else { // Event time is sooner than the maximum threshold. currentTimestampUs = nextCommandTimestampUs; - nextChunk.outputFrontSample(trackOutput); + nextChunk.outputFrontSample( + checkStateNotNull(trackOutput), /* skipNoteEvents= */ false); nextChunk.populateFrontTrackEvent(); } @@ -223,9 +229,8 @@ public final class MidiExtractor implements Extractor, SeekMap { return result; case STATE_INITIALIZED: case STATE_RELEASED: - throw new IllegalStateException(); default: - throw new IllegalStateException(); // Should never happen. + throw new IllegalStateException(); } } @@ -333,12 +338,13 @@ public final class MidiExtractor implements Extractor, SeekMap { } private void outputEmptySample() { - trackOutput.sampleMetadata( - currentTimestampUs, - /* flags= */ C.BUFFER_FLAG_KEY_FRAME, - /* size= */ 0, - /* offset= */ 0, - /* cryptoData= */ null); + checkStateNotNull(trackOutput) + .sampleMetadata( + currentTimestampUs, + /* flags= */ 0, + /* size= */ 0, + /* offset= */ 0, + /* cryptoData= */ null); } private void seekChunksTo(long seekTimeUs) throws ParserException { @@ -347,12 +353,64 @@ public final class MidiExtractor implements Extractor, SeekMap { long nextTimestampUs = nextChunk.peekNextTimestampUs(); if (nextTimestampUs != C.TIME_UNSET && nextTimestampUs < seekTimeUs) { - nextChunk.outputFrontSample( - trackOutput, C.BUFFER_FLAG_KEY_FRAME, /* skipNoteEvents= */ true); + nextChunk.outputFrontSample(checkStateNotNull(trackOutput), /* skipNoteEvents= */ true); nextChunk.populateFrontTrackEvent(); trackPriorityQueue.add(nextChunk); } } trackPriorityQueue.addAll(trackChunkList); } + + /** + * A {@link TrackOutput} wrapper that marks only the first sample as a key-frame. + * + *

Only the first sample is marked as a key-frame so that seeking requires the player to seek + * to the beginning of the MIDI input and output all non Note-On and Note-Off events to the {@link + * MidiDecoder}. + */ + private static final class SingleKeyFrameTrackOutput implements TrackOutput { + private final TrackOutput trackOutput; + private int outputSampleCount; + + private SingleKeyFrameTrackOutput(TrackOutput trackOutput) { + this.trackOutput = trackOutput; + } + + @Override + public void format(Format format) { + trackOutput.format(format); + } + + @Override + public int sampleData( + DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart) + throws IOException { + return trackOutput.sampleData(input, length, allowEndOfInput, sampleDataPart); + } + + @Override + public void sampleData(ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) { + trackOutput.sampleData(data, length, sampleDataPart); + } + + @Override + public void sampleMetadata( + long timeUs, + @C.BufferFlags int flags, + int size, + int offset, + @Nullable CryptoData cryptoData) { + // No MIDI sample should be marked as key-frame + checkState((flags & C.BUFFER_FLAG_KEY_FRAME) == 0); + if (outputSampleCount == 0) { + flags |= C.BUFFER_FLAG_KEY_FRAME; + } + trackOutput.sampleMetadata(timeUs, flags, size, offset, cryptoData); + outputSampleCount++; + } + + public void reset() { + outputSampleCount = 0; + } + } } diff --git a/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/TrackChunk.java b/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/TrackChunk.java index 1ea32e94b1..4a36100cee 100644 --- a/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/TrackChunk.java +++ b/libraries/decoder_midi/src/main/java/androidx/media3/decoder/midi/TrackChunk.java @@ -90,25 +90,13 @@ import java.util.ArrayList; ticksPerQuarterNote); } - /** - * Outputs the front sample to {@code trackOutput}, flagged as a {@linkplain - * C#BUFFER_FLAG_KEY_FRAME key frame}. - */ - public void outputFrontSample(TrackOutput trackOutput) { - outputFrontSample( - /* trackOutput= */ trackOutput, - /* flags= */ C.BUFFER_FLAG_KEY_FRAME, - /* skipNoteEvents= */ false); - } - /** * Outputs the current track event to {@code trackOutput}. * * @param trackOutput The {@link TrackOutput} to output samples to. - * @param flags {@link C.BufferFlags} to mark the buffer with. * @param skipNoteEvents Whether note events should be skipped. */ - public void outputFrontSample(TrackOutput trackOutput, int flags, boolean skipNoteEvents) { + public void outputFrontSample(TrackOutput trackOutput, boolean skipNoteEvents) { if (!currentTrackEvent.isPopulated()) { return; } @@ -149,7 +137,7 @@ import java.util.ArrayList; trackOutput.sampleData(sampleData, sampleSize); trackOutput.sampleMetadata( lastOutputEventTimestampUs, - /* flags= */ flags, + /* flags= */ 0, /* size= */ sampleSize, /* offset= */ 0, /* cryptoData= */ null); @@ -207,10 +195,8 @@ import java.util.ArrayList; return 1; } else if (otherTimestampUs == C.TIME_UNSET) { return -1; - } else if (thisTimestampUs < otherTimestampUs) { - return -1; } else { - return 1; + return Long.compare(thisTimestampUs, otherTimestampUs); } } diff --git a/libraries/decoder_midi/src/test/java/androidx/media3/decoder/midi/TrackChunkTest.java b/libraries/decoder_midi/src/test/java/androidx/media3/decoder/midi/TrackChunkTest.java index 3889676636..e6d7cb35b4 100644 --- a/libraries/decoder_midi/src/test/java/androidx/media3/decoder/midi/TrackChunkTest.java +++ b/libraries/decoder_midi/src/test/java/androidx/media3/decoder/midi/TrackChunkTest.java @@ -52,7 +52,7 @@ public class TrackChunkTest { /* tempoListener= */ mock(TrackChunk.TempoChangedListener.class)); trackChunk.populateFrontTrackEvent(); - trackChunk.outputFrontSample(fakeTrackOutput); + trackChunk.outputFrontSample(fakeTrackOutput, /* skipNoteEvents= */ false); assertThat(fakeTrackOutput.getSampleTimeUs(/* index= */ 0)).isEqualTo(/* expected= */ 0); trackChunk.addTempoChange(/* tempoBpm= */ 180, /* ticks= */ 480); @@ -60,7 +60,7 @@ public class TrackChunkTest { trackChunk.addTempoChange(/* tempoBpm= */ 300, /* ticks= */ 1440); trackChunk.populateFrontTrackEvent(); - trackChunk.outputFrontSample(fakeTrackOutput); + trackChunk.outputFrontSample(fakeTrackOutput, /* skipNoteEvents= */ false); assertThat(fakeTrackOutput.getSampleTimeUs(/* index= */ 1)).isEqualTo(/* expected= */ 1283333); } } diff --git a/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.0.dump b/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.0.dump index 013f97a05c..0aa0e33082 100644 --- a/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.0.dump @@ -16,382 +16,382 @@ track 0: data = length 7, hash C95FA520 sample 1: time = 0 - flags = 1 + flags = 0 data = length 5, hash 1CF3DA7 sample 2: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFED75B sample 3: time = 100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 4: time = 200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 5: time = 300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 6: time = 400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 7: time = 500000 - flags = 1 + flags = 0 data = length 3, hash FFFED733 sample 8: time = 500000 - flags = 1 + flags = 0 data = length 3, hash FFFED751 sample 9: time = 600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 10: time = 700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 11: time = 800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 12: time = 900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 13: time = 1000000 - flags = 1 + flags = 0 data = length 3, hash FFFED733 sample 14: time = 1000000 - flags = 1 + flags = 0 data = length 3, hash FFFED839 sample 15: time = 1100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 16: time = 1200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 17: time = 1300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 18: time = 1400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 19: time = 1500000 - flags = 1 + flags = 0 data = length 3, hash FFFED80C sample 20: time = 1500000 - flags = 1 + flags = 0 data = length 3, hash FFFED83E sample 21: time = 1600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 22: time = 1700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 23: time = 1800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 24: time = 1900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 25: time = 2000000 - flags = 1 + flags = 0 data = length 3, hash FFFED80C sample 26: time = 2000000 - flags = 1 + flags = 0 data = length 3, hash FFFED877 sample 27: time = 2100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 28: time = 2200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 29: time = 2300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 30: time = 2400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 31: time = 2500000 - flags = 1 + flags = 0 data = length 3, hash FFFED84A sample 32: time = 2500000 - flags = 1 + flags = 0 data = length 3, hash FFFED87C sample 33: time = 2600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 34: time = 2700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 35: time = 2800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 36: time = 2900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 37: time = 3000000 - flags = 1 + flags = 0 data = length 3, hash FFFED84A sample 38: time = 3000000 - flags = 1 + flags = 0 data = length 3, hash FFFED82F sample 39: time = 3100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 40: time = 3200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 41: time = 3300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 42: time = 3400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 43: time = 3500000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 44: time = 3600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 45: time = 3700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 46: time = 3800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 47: time = 3900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 48: time = 4000000 - flags = 1 + flags = 0 data = length 3, hash FFFED80C sample 49: time = 4000000 - flags = 1 + flags = 0 data = length 3, hash FFFED800 sample 50: time = 4100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 51: time = 4200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 52: time = 4300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 53: time = 4400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 54: time = 4500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7CE sample 55: time = 4500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7FB sample 56: time = 4600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 57: time = 4700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 58: time = 4800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 59: time = 4900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 60: time = 5000000 - flags = 1 + flags = 0 data = length 3, hash FFFED7CE sample 61: time = 5000000 - flags = 1 + flags = 0 data = length 3, hash FFFED7E1 sample 62: time = 5100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 63: time = 5200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 64: time = 5250000 - flags = 1 + flags = 0 data = length 3, hash FFFED7AF sample 65: time = 5350000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 66: time = 5450000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 67: time = 5500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7D7 sample 68: time = 5600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 69: time = 5700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 70: time = 5750000 - flags = 1 + flags = 0 data = length 3, hash FFFED7AF sample 71: time = 5850000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 72: time = 5950000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 73: time = 6000000 - flags = 1 + flags = 0 data = length 3, hash FFFED79E sample 74: time = 6100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 75: time = 6200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 76: time = 6250000 - flags = 1 + flags = 0 data = length 3, hash FFFED771 sample 77: time = 6350000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 78: time = 6450000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 79: time = 6500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7A3 sample 80: time = 6600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 81: time = 6700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 82: time = 6750000 - flags = 1 + flags = 0 data = length 3, hash FFFED771 sample 83: time = 6850000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 84: time = 6950000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 85: time = 7000000 - flags = 1 + flags = 0 data = length 3, hash FFFED751 sample 86: time = 7100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 87: time = 7200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 88: time = 7300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 89: time = 7400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 90: time = 7500000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 91: time = 7600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 92: time = 7700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 93: time = 7800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 94: time = 7900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 95: time = 8000000 - flags = 1 + flags = 0 data = length 3, hash FFFED733 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.unknown_length.dump index 013f97a05c..0aa0e33082 100644 --- a/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/midi/Twinkle.mid.unknown_length.dump @@ -16,382 +16,382 @@ track 0: data = length 7, hash C95FA520 sample 1: time = 0 - flags = 1 + flags = 0 data = length 5, hash 1CF3DA7 sample 2: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFED75B sample 3: time = 100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 4: time = 200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 5: time = 300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 6: time = 400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 7: time = 500000 - flags = 1 + flags = 0 data = length 3, hash FFFED733 sample 8: time = 500000 - flags = 1 + flags = 0 data = length 3, hash FFFED751 sample 9: time = 600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 10: time = 700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 11: time = 800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 12: time = 900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 13: time = 1000000 - flags = 1 + flags = 0 data = length 3, hash FFFED733 sample 14: time = 1000000 - flags = 1 + flags = 0 data = length 3, hash FFFED839 sample 15: time = 1100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 16: time = 1200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 17: time = 1300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 18: time = 1400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 19: time = 1500000 - flags = 1 + flags = 0 data = length 3, hash FFFED80C sample 20: time = 1500000 - flags = 1 + flags = 0 data = length 3, hash FFFED83E sample 21: time = 1600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 22: time = 1700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 23: time = 1800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 24: time = 1900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 25: time = 2000000 - flags = 1 + flags = 0 data = length 3, hash FFFED80C sample 26: time = 2000000 - flags = 1 + flags = 0 data = length 3, hash FFFED877 sample 27: time = 2100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 28: time = 2200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 29: time = 2300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 30: time = 2400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 31: time = 2500000 - flags = 1 + flags = 0 data = length 3, hash FFFED84A sample 32: time = 2500000 - flags = 1 + flags = 0 data = length 3, hash FFFED87C sample 33: time = 2600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 34: time = 2700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 35: time = 2800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 36: time = 2900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 37: time = 3000000 - flags = 1 + flags = 0 data = length 3, hash FFFED84A sample 38: time = 3000000 - flags = 1 + flags = 0 data = length 3, hash FFFED82F sample 39: time = 3100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 40: time = 3200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 41: time = 3300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 42: time = 3400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 43: time = 3500000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 44: time = 3600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 45: time = 3700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 46: time = 3800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 47: time = 3900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 48: time = 4000000 - flags = 1 + flags = 0 data = length 3, hash FFFED80C sample 49: time = 4000000 - flags = 1 + flags = 0 data = length 3, hash FFFED800 sample 50: time = 4100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 51: time = 4200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 52: time = 4300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 53: time = 4400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 54: time = 4500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7CE sample 55: time = 4500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7FB sample 56: time = 4600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 57: time = 4700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 58: time = 4800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 59: time = 4900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 60: time = 5000000 - flags = 1 + flags = 0 data = length 3, hash FFFED7CE sample 61: time = 5000000 - flags = 1 + flags = 0 data = length 3, hash FFFED7E1 sample 62: time = 5100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 63: time = 5200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 64: time = 5250000 - flags = 1 + flags = 0 data = length 3, hash FFFED7AF sample 65: time = 5350000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 66: time = 5450000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 67: time = 5500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7D7 sample 68: time = 5600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 69: time = 5700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 70: time = 5750000 - flags = 1 + flags = 0 data = length 3, hash FFFED7AF sample 71: time = 5850000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 72: time = 5950000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 73: time = 6000000 - flags = 1 + flags = 0 data = length 3, hash FFFED79E sample 74: time = 6100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 75: time = 6200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 76: time = 6250000 - flags = 1 + flags = 0 data = length 3, hash FFFED771 sample 77: time = 6350000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 78: time = 6450000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 79: time = 6500000 - flags = 1 + flags = 0 data = length 3, hash FFFED7A3 sample 80: time = 6600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 81: time = 6700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 82: time = 6750000 - flags = 1 + flags = 0 data = length 3, hash FFFED771 sample 83: time = 6850000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 84: time = 6950000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 85: time = 7000000 - flags = 1 + flags = 0 data = length 3, hash FFFED751 sample 86: time = 7100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 87: time = 7200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 88: time = 7300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 89: time = 7400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 90: time = 7500000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 91: time = 7600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 92: time = 7700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 93: time = 7800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 94: time = 7900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 95: time = 8000000 - flags = 1 + flags = 0 data = length 3, hash FFFED733 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/midi/mid_note_tempo_changes_simple.mid.dump b/libraries/test_data/src/test/assets/extractordumps/midi/mid_note_tempo_changes_simple.mid.dump index 639be7c871..6152c3a9d0 100644 --- a/libraries/test_data/src/test/assets/extractordumps/midi/mid_note_tempo_changes_simple.mid.dump +++ b/libraries/test_data/src/test/assets/extractordumps/midi/mid_note_tempo_changes_simple.mid.dump @@ -16,74 +16,74 @@ track 0: data = length 3, hash 70FB sample 1: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFEDCE7 sample 2: time = 0 - flags = 1 + flags = 0 data = length 7, hash C95FA238 sample 3: time = 0 - flags = 1 + flags = 0 data = length 6, hash 37A83E76 sample 4: time = 100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 5: time = 200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 6: time = 300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 7: time = 400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 8: time = 500000 - flags = 1 + flags = 0 data = length 6, hash 37A84514 sample 9: time = 600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 10: time = 700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 11: time = 800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 12: time = 833333 - flags = 1 + flags = 0 data = length 6, hash 37A83493 sample 13: time = 933333 - flags = 1 + flags = 0 data = length 0, hash 1 sample 14: time = 1033333 - flags = 1 + flags = 0 data = length 0, hash 1 sample 15: time = 1083333 - flags = 1 + flags = 0 data = length 6, hash 37A83CA6 sample 16: time = 1183333 - flags = 1 + flags = 0 data = length 0, hash 1 sample 17: time = 1283333 - flags = 1 + flags = 0 data = length 3, hash FFFEA058 sample 18: time = 1283333 - flags = 1 + flags = 0 data = length 3, hash FFFF4CA9 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/midi/multi_note_tempo_changes.mid.dump b/libraries/test_data/src/test/assets/extractordumps/midi/multi_note_tempo_changes.mid.dump index 0542bd5814..a7e9bace9b 100644 --- a/libraries/test_data/src/test/assets/extractordumps/midi/multi_note_tempo_changes.mid.dump +++ b/libraries/test_data/src/test/assets/extractordumps/midi/multi_note_tempo_changes.mid.dump @@ -16,122 +16,122 @@ track 0: data = length 3, hash 70FB sample 1: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFF5A77 sample 2: time = 0 - flags = 1 + flags = 0 data = length 7, hash C95FA238 sample 3: time = 0 - flags = 1 + flags = 0 data = length 3, hash 70FB sample 4: time = 0 - flags = 1 + flags = 0 data = length 6, hash 37A83E76 sample 5: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFF4D46 sample 6: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFF4D0D sample 7: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFF4DA4 sample 8: time = 0 - flags = 1 + flags = 0 data = length 3, hash 40 sample 9: time = 0 - flags = 1 + flags = 0 data = length 2, hash FFFFFC20 sample 10: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFEDCE7 sample 11: time = 100000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 12: time = 200000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 13: time = 300000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 14: time = 400000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 15: time = 500000 - flags = 1 + flags = 0 data = length 6, hash 37A84514 sample 16: time = 500000 - flags = 1 + flags = 0 data = length 3, hash FFFEDD63 sample 17: time = 600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 18: time = 700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 19: time = 800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 20: time = 833333 - flags = 1 + flags = 0 data = length 3, hash FFFEA0D4 sample 21: time = 833333 - flags = 1 + flags = 0 data = length 6, hash 37A83493 sample 22: time = 833333 - flags = 1 + flags = 0 data = length 3, hash FFFEDDC0 sample 23: time = 933333 - flags = 1 + flags = 0 data = length 0, hash 1 sample 24: time = 1033333 - flags = 1 + flags = 0 data = length 0, hash 1 sample 25: time = 1083333 - flags = 1 + flags = 0 data = length 6, hash 37A83CA6 sample 26: time = 1083333 - flags = 1 + flags = 0 data = length 3, hash FFFEA131 sample 27: time = 1083333 - flags = 1 + flags = 0 data = length 3, hash FFFEDE1D sample 28: time = 1183333 - flags = 1 + flags = 0 data = length 0, hash 1 sample 29: time = 1283333 - flags = 1 + flags = 0 data = length 3, hash FFFEA058 sample 30: time = 1283333 - flags = 1 + flags = 0 data = length 3, hash FFFEA18E tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/midi/seek_test_with_non_note_events.mid.dump b/libraries/test_data/src/test/assets/extractordumps/midi/seek_test_with_non_note_events.mid.dump index e55a1dd321..7990ac0b80 100644 --- a/libraries/test_data/src/test/assets/extractordumps/midi/seek_test_with_non_note_events.mid.dump +++ b/libraries/test_data/src/test/assets/extractordumps/midi/seek_test_with_non_note_events.mid.dump @@ -16,90 +16,90 @@ track 0: data = length 3, hash 70FB sample 1: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFF56B6 sample 2: time = 0 - flags = 1 + flags = 0 data = length 7, hash C95FA238 sample 3: time = 0 - flags = 1 + flags = 0 data = length 3, hash FFFF494C sample 4: time = 0 - flags = 1 + flags = 0 data = length 6, hash 37A83E76 sample 5: time = 4999999 - flags = 1 + flags = 0 data = length 3, hash 8DE sample 6: time = 5500000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 7: time = 5600000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 8: time = 5700000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 9: time = 5800000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 10: time = 5900000 - flags = 1 + flags = 0 data = length 0, hash 1 sample 11: time = 5999999 - flags = 1 + flags = 0 data = length 3, hash FFFED7B2 sample 12: time = 6099999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 13: time = 6199999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 14: time = 6299999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 15: time = 6399999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 16: time = 6499999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 17: time = 6599999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 18: time = 6699999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 19: time = 6799999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 20: time = 6899999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 21: time = 6999999 - flags = 1 + flags = 0 data = length 0, hash 1 sample 22: time = 7041665 - flags = 1 + flags = 0 data = length 3, hash FFFE9B23 tracksEnded = true