blob: a2c09b88292dab5e7d473bb25b222c09d7a8fb20 [file] [log] [blame]
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +00001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef MEDIA_MIDI_MIDI_MESSAGE_QUEUE_H_
6#define MEDIA_MIDI_MIDI_MESSAGE_QUEUE_H_
7
avi793390d2015-12-22 22:22:36 -08008#include <stddef.h>
Avi Drissman3528fd02015-12-18 20:11:31 -05009#include <stdint.h>
10
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000011#include <vector>
12
Prashant Malanif55fb1d2019-08-08 17:00:08 +000013#include "base/containers/circular_deque.h"
Avi Drissman3528fd02015-12-18 20:11:31 -050014#include "base/macros.h"
brettw49ff0172015-05-05 12:43:04 -070015#include "media/midi/midi_export.h"
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000016
toyoshime147c5e2015-05-07 21:58:31 -070017namespace midi {
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000018
19// A simple message splitter for possibly unsafe/corrupted MIDI data stream.
20// This class allows you to:
21// - maintain fragmented MIDI message.
22// - skip any invalid data sequence.
23// - reorder MIDI messages so that "System Real Time Message", which can be
24// inserted at any point of the byte stream, is placed at the boundary of
25// complete MIDI messages.
26// - (Optional) reconstruct complete MIDI messages from data stream where
27// MIDI status byte is abbreviated (a.k.a. "running status").
28//
29// Example (pseudo message loop):
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000030// MidiMessageQueue queue(true); // true to support "running status"
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000031// while (true) {
32// if (is_incoming_midi_data_available()) {
Avi Drissman3528fd02015-12-18 20:11:31 -050033// std::vector<uint8_t> incoming_data;
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000034// read_incoming_midi_data(&incoming_data)
35// queue.Add(incoming_data);
36// }
37// while (true) {
Avi Drissman3528fd02015-12-18 20:11:31 -050038// std::vector<uint8_t> next_message;
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000039// queue.Get(&next_message);
40// if (!next_message.empty())
41// dispatch(next_message);
42// }
43// }
brettw49ff0172015-05-05 12:43:04 -070044class MIDI_EXPORT MidiMessageQueue {
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000045 public:
46 // Initializes the queue. Set true to |allow_running_status| to enable
47 // "MIDI running status" reconstruction.
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000048 explicit MidiMessageQueue(bool allow_running_status);
Peter Boström53634032021-09-22 20:24:34 +000049
50 MidiMessageQueue(const MidiMessageQueue&) = delete;
51 MidiMessageQueue& operator=(const MidiMessageQueue&) = delete;
52
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000053 ~MidiMessageQueue();
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000054
55 // Enqueues |data| to the internal buffer.
Avi Drissman3528fd02015-12-18 20:11:31 -050056 void Add(const std::vector<uint8_t>& data);
57 void Add(const uint8_t* data, size_t length);
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000058
59 // Fills the next complete MIDI message into |message|. If |message| is
60 // not empty, the data sequence falls into one of the following types of
61 // MIDI message.
62 // - Single "Channel Voice Message" (w/o "System Real Time Messages")
63 // - Single "Channel Mode Message" (w/o "System Real Time Messages")
64 // - Single "System Exclusive Message" (w/o "System Real Time Messages")
65 // - Single "System Common Message" (w/o "System Real Time Messages")
66 // - Single "System Real Time message"
67 // |message| is empty if there is no complete MIDI message any more.
Avi Drissman3528fd02015-12-18 20:11:31 -050068 void Get(std::vector<uint8_t>* message);
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000069
70 private:
Prashant Malanif55fb1d2019-08-08 17:00:08 +000071 base::circular_deque<uint8_t> queue_;
Avi Drissman3528fd02015-12-18 20:11:31 -050072 std::vector<uint8_t> next_message_;
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000073 const bool allow_running_status_;
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000074};
75
toyoshime147c5e2015-05-07 21:58:31 -070076} // namespace midi
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000077
78#endif // MEDIA_MIDI_MIDI_MESSAGE_QUEUE_H_