File: midiparser_qt.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (153 lines) | stat: -rw-r--r-- 4,731 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef AUDIO_MIDIPARSER_QT_H
#define AUDIO_MIDIPARSER_QT_H

#include "audio/midiparser.h"
#include "common/array.h"
#include "common/hashmap.h"
#include "common/queue.h"
#include "common/formats/quicktime.h"

/**
 * @defgroup audio_midiparser_qt QT MIDI parser
 * @ingroup audio
 *
 * @brief The QuickTime Music version of MidiParser class.
 * @{
 */

/**
 * The QuickTime Music version of MidiParser.
 *
 * QuickTime Music is actually a superset of MIDI. It has its own custom
 * instruments and supports more than 15 non-percussion channels. It also
 * has custom control changes and a more advanced pitch bend (which we
 * convert to GM pitch bend as best as possible). We then use the fallback
 * GM instrument that each QuickTime instrument definition has to provide.
 *
 * Furthermore, Apple's documentation on this is terrible. You know
 * documentation is bad when it contradicts itself three times on the same
 * subject (like about setting the GM instrument field to percussion).
 *
 * This is as close to a proper QuickTime Music parser as we can currently
 * implement using our MidiParser interface.
 */
class MidiParser_QT : public MidiParser, public Common::QuickTimeParser {
public:
	MidiParser_QT(int8 source = -1) : _source(source) {}
	~MidiParser_QT() {}

	// MidiParser
	bool loadMusic(byte *data, uint32 size) override;
	void unloadMusic() override;

	/**
	 * Load the MIDI from a 'Tune' resource
	 */
	bool loadFromTune(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);

	/**
	 * Load the MIDI from a QuickTime stream
	 */
	bool loadFromContainerStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);

	/**
	 * Load the MIDI from a QuickTime file
	 */
	bool loadFromContainerFile(const Common::Path &fileName);

protected:
	// MidiParser
	void parseNextEvent(EventInfo &info) override;
	void resetTracking() override;

	void sendToDriver(uint32 b) override;
	void sendMetaEventToDriver(byte type, byte *data, uint16 length) override;

	// QuickTimeParser
	SampleDesc *readSampleDesc(Track *track, uint32 format, uint32 descSize) override;

	/**
	 * The source number to use when sending MIDI messages to the driver.
	 * When using multiple sources, use source 0 and higher. This must be
	 * used when source volume or channel locking is used.
	 * By default this is -1, which means the parser is the only source
	 * of MIDI messages and multiple source functionality is disabled.
	 */
	int8 _source;

private:
	struct MIDITrackInfo {
		byte *data;
		uint32 size;
		uint32 timeScale;
	};

	struct PartStatus {
		uint32 instrument;
		byte volume;
		byte pan;
		uint16 pitchBend;
	};

	class MIDISampleDesc : public SampleDesc {
	public:
		MIDISampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag);
		~MIDISampleDesc() {}

		byte *_requestData;
		uint32 _requestSize;
	};

	uint32 readNextEvent();
	void handleGeneralEvent(uint32 control);
	void handleControllerEvent(uint32 control, uint32 part, byte intPart, byte fracPart);
	void handleNoteEvent(uint32 part, byte pitch, byte velocity, uint32 length);

	void definePart(uint32 part, uint32 instrument);
	void setupPart(uint32 part);

	byte getChannel(uint32 part);
	bool isChannelAllocated(byte channel) const;
	byte findFreeChannel(uint32 part);
	void deallocateFreeChannel();
	void deallocateChannel(byte channel);
	bool allChannelsAllocated() const;

	byte *readWholeTrack(Common::QuickTimeParser::Track *track, uint32 &trackSize);

	Common::Array<MIDITrackInfo> _trackInfo;
	Common::Queue<EventInfo> _queuedEvents;

	typedef Common::HashMap<uint, PartStatus> PartMap;
	PartMap _partMap;

	typedef Common::HashMap<uint, byte> ChannelMap;
	ChannelMap _channelMap;

	void initFromContainerTracks();
	void initCommon();
	uint32 readUint32();
};
/** @} */
#endif