ScummVM API documentation
music.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef MACS2_MUSIC_H
23 #define MACS2_MUSIC_H
24 
25 #include "audio/mididrv.h"
26 #include "audio/midiplayer.h"
27 #include "common/array.h"
28 #include "common/path.h"
29 #include "common/scummsys.h"
30 
31 class MidiParser;
32 
33 namespace OPL {
34 class OPL;
35 }
36 
37 namespace Macs2 {
38 
44 public:
45  SmfMidiPlayer();
46  ~SmfMidiPlayer() override = default;
47 
48  void playFile(const Common::Path &path, bool loop = false);
49 };
50 
61 class Music : public MidiDriver_BASE {
62 public:
63  Music();
64  ~Music();
65 
66  void init();
67  void deinit();
68 
70  bool playSongData(const Common::Array<uint8> &data);
72  bool playMidiFile(const Common::Path &path, bool loop = false);
74  void stopMusic();
76  void setVolume(uint16 volume);
81  void setSmfVolumeFromAttenuation(uint16 gameAttenuation);
83  void syncSmfVolume();
88  void setSmfDucked(bool ducked, uint16 talkVolPercent = 50);
89  bool isPlaybackReady() const { return _adlibPlaybackReady; }
90  bool isMidiFilePlaying() const;
91  bool hasAdlibBackend() const { return _opl != nullptr; }
92 
93  // MidiDriver_BASE interface
94  void send(uint32 b) override;
95  void metaEvent(byte type, const byte *data, uint16 length) override;
96 
97  // Debug state for ImGui visualization
98  static constexpr int kDebugRingSize = 512;
99  static constexpr int kChannels = 9;
101  uint8 note = 0xFF;
102  uint8 channel = 0xFF;
103  uint8 volume = 0;
104  bool active = false;
105  };
106  struct DebugState {
107  VoiceDebugState voices[kChannels];
108  uint8 masterVolume = 0;
109  uint16 activeMusicSlot = 0;
110  uint8 statusFlags = 0;
111  uint32 nextEventTimer = 0;
112  uint16 numOplChannels = 0;
113  float regHistory[kChannels][kDebugRingSize] = {};
114  int ringPos = 0;
115  };
116  DebugState _debug;
117 
118 private:
119  void onTimer();
120  void writeReg(byte reg, byte value);
121  uint8 readReg(byte reg) const { return _regShadow[reg]; }
122 
123  void noteOn(byte channel, byte note, byte velocity);
124  void noteOff(byte channel, byte note);
125  void programChange(byte channel, byte program);
126  void controlChange(byte channel, byte control, byte value);
127 
128  void loadInstrument(uint8 voice, uint8 program);
129  void setFrequency(uint8 voice, uint8 note, uint8 pitchBend);
130  void silenceAll();
131  void updateDebugState();
132 
133  OPL::OPL *_opl;
134  MidiParser *_parser;
135  bool _playing;
136  bool _adlibPlaybackReady = true;
137 
138  // OPL state
139  byte _regShadow[256];
140  uint8 _masterVolume;
141  uint8 _numOplChannels;
142 
143  // Voice allocation (age-based, matching original)
144  uint8 _voiceAge[kChannels];
145  uint8 _voiceMidiChannel[kChannels];
146  uint8 _voiceInstrument[kChannels];
147  uint8 _voiceNote[kChannels];
148 
149  // Channel state
150  uint8 _channelPrograms[16];
151  uint8 _channelPitchBend[16];
152 
153  // Song data (kept alive for MidiParser which doesn't copy)
154  Common::Array<uint8> _songData;
155 
156  // Instrument data from EXE (16 bytes per instrument, 11 used)
157  Common::Array<uint8> _instrumentData;
158  uint16 _instrumentDataOffset;
159 
160  SmfMidiPlayer *_smf;
161  bool _smfDucked;
162  int _smfVolumeBeforeDuck;
163 
164  void stopAdlibPlayback();
165  void stopSmfPlayback();
166  bool ensureSmfPlayer();
167 };
168 
169 } // End of namespace Macs2
170 
171 #endif
Definition: midiplayer.h:63
Definition: music.h:43
Definition: path.h:52
Definition: music.h:61
Definition: mididrv.h:114
Definition: music.h:106
Definition: fmopl.h:35
Definition: music.h:100
Definition: actionbar.h:31
Definition: midiparser.h:354
Definition: fmopl.h:116