1 /*
2 * This file is part of EasyRPG Player.
3 *
4 * EasyRPG Player is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * EasyRPG Player is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <array>
19 #include <algorithm>
20 #include "audio_decoder_midi.h"
21 #include "midisequencer.h"
22 #include "output.h"
23
24 using namespace std::chrono_literals;
25
26 constexpr int AudioDecoderMidi::midi_default_tempo;
27
28 constexpr int bytes_per_sample = sizeof(int16_t) * 2;
29
30 // ~1.5 ms of MIDI message resolution
31 #if EP_MIDI_FREQ <= 11025
32 constexpr int sample_divider = 4;
33 #elif EP_MIDI_FREQ <= 22050
34 constexpr int sample_divider = 2;
35 #else
36 constexpr int sample_divider = 1;
37 #endif
38 constexpr int samples_per_play = 64 / sample_divider;
39
40 static const uint8_t midi_event_control_change = 0b1011;
41 static const uint8_t midi_control_volume = 7;
42 static const uint8_t midi_control_all_sound_off = 120;
43 static const uint8_t midi_control_all_note_off = 123;
44 static const uint8_t midi_control_reset_all_controller = 121;
45
midimsg_make(uint8_t event_type,uint8_t channel,uint8_t value1,uint8_t value2)46 static uint32_t midimsg_make(uint8_t event_type, uint8_t channel, uint8_t value1, uint8_t value2) {
47 uint32_t msg = 0;
48 msg |= (((event_type << 4) & 0xF0) | (channel & 0x0F)) & 0x0000FF;
49 msg |= (value1 << 8) & 0x00FF00;
50 msg |= (value2 << 16) & 0xFF0000;
51 return msg;
52 }
53
midimsg_all_note_off(uint8_t channel)54 static uint32_t midimsg_all_note_off(uint8_t channel) {
55 return midimsg_make(midi_event_control_change, channel, midi_control_all_note_off, 0);
56 }
57
midimsg_all_sound_off(uint8_t channel)58 static uint32_t midimsg_all_sound_off(uint8_t channel) {
59 return midimsg_make(midi_event_control_change, channel, midi_control_all_sound_off, 0);
60 }
61
midimsg_volume(uint8_t channel,uint8_t volume)62 static uint32_t midimsg_volume(uint8_t channel, uint8_t volume) {
63 return midimsg_make(midi_event_control_change, channel, midi_control_volume, volume);
64 }
65
midimsg_reset_all_controller(uint8_t channel)66 static uint32_t midimsg_reset_all_controller(uint8_t channel) {
67 return midimsg_make(midi_event_control_change, channel, midi_control_reset_all_controller, 0);
68 }
69
midimsg_get_event_type(uint32_t msg)70 static inline uint8_t midimsg_get_event_type(uint32_t msg) {
71 return (msg & 0x0000F0) >> 4;
72 }
73
midimsg_get_channel(uint32_t msg)74 static inline uint8_t midimsg_get_channel(uint32_t msg) {
75 return (msg & 0x00000F);
76 }
77
midimsg_get_value1(uint32_t msg)78 static inline uint8_t midimsg_get_value1(uint32_t msg) {
79 return (msg & 0x00FF00) >> 8;
80 }
81
midimsg_get_value2(uint32_t msg)82 static inline uint8_t midimsg_get_value2(uint32_t msg) {
83 return (msg & 0xFF0000) >> 16;
84 }
85
AudioDecoderMidi(std::unique_ptr<MidiDecoder> mididec)86 AudioDecoderMidi::AudioDecoderMidi(std::unique_ptr<MidiDecoder> mididec)
87 : mididec(std::move(mididec)) {
88 seq = std::make_unique<midisequencer::sequencer>();
89 channel_volumes.fill(127);
90 }
91
~AudioDecoderMidi()92 AudioDecoderMidi::~AudioDecoderMidi() {
93 reset();
94 }
95
read_func(void * instance)96 static int read_func(void* instance) {
97 AudioDecoderMidi* midi = reinterpret_cast<AudioDecoderMidi*>(instance);
98
99 if (midi->file_buffer_pos >= midi->file_buffer.size()) {
100 return EOF;
101 }
102
103 return midi->file_buffer[midi->file_buffer_pos++];
104 }
105
Open(Filesystem_Stream::InputStream stream)106 bool AudioDecoderMidi::Open(Filesystem_Stream::InputStream stream) {
107 Reset();
108 seq->clear();
109
110 file_buffer_pos = 0;
111 file_buffer = Utils::ReadStream(stream);
112
113 if (!seq->load(this, read_func)) {
114 error_message = "Midi: Error reading file";
115 return false;
116 }
117 seq->rewind();
118 tempo.emplace_back(this, midi_default_tempo);
119 mtime = seq->get_start_skipping_silence();
120 seq->play(mtime, this);
121
122 if (!mididec->SupportsMidiMessages()) {
123 if (!mididec->Open(file_buffer)) {
124 error_message = "Internal Midi: Error reading file";
125 return false;
126 }
127
128 mididec->Seek(tempo.back().GetSamples(mtime), std::ios_base::beg);
129 }
130
131 return true;
132 }
133
Pause()134 void AudioDecoderMidi::Pause() {
135 paused = true;
136 for (int i = 0; i < 16; i++) {
137 uint32_t msg = midimsg_volume(i, 0);
138 mididec->SendMidiMessage(msg);
139 }
140 }
141
Resume()142 void AudioDecoderMidi::Resume() {
143 paused = false;
144 for (int i = 0; i < 16; i++) {
145 uint32_t msg = midimsg_volume(i, static_cast<uint8_t>(channel_volumes[i] * volume));
146 mididec->SendMidiMessage(msg);
147 }
148 }
149
GetVolume() const150 int AudioDecoderMidi::GetVolume() const {
151 // When handled by Midi messages fake a 100 otherwise the volume is adjusted twice
152
153 if (!mididec->SupportsMidiMessages()) {
154 return static_cast<int>(log_volume);
155 }
156
157 return 100;
158 }
159
SetVolume(int new_volume)160 void AudioDecoderMidi::SetVolume(int new_volume) {
161 // cancel any pending fades
162 fade_steps = 0;
163
164 volume = static_cast<float>(new_volume) / 100.0f;
165 for (int i = 0; i < 16; i++) {
166 uint32_t msg = midimsg_volume(i, static_cast<uint8_t>(channel_volumes[i] * volume));
167 mididec->SendMidiMessage(msg);
168 }
169
170 if (!mididec->SupportsMidiMessages()) {
171 log_volume = AdjustVolume(volume * 100.0f);
172 }
173 }
174
SetFade(int end,std::chrono::milliseconds duration)175 void AudioDecoderMidi::SetFade(int end, std::chrono::milliseconds duration) {
176 fade_steps = 0;
177 last_fade_mtime = 0us;
178
179 if (duration <= 0ms) {
180 SetVolume(end);
181 return;
182 }
183
184 fade_volume_end = end / 100.0f;
185 fade_steps = duration.count() / 100.0;
186 delta_volume_step = (fade_volume_end - volume) / fade_steps;
187 }
188
Seek(std::streamoff offset,std::ios_base::seekdir origin)189 bool AudioDecoderMidi::Seek(std::streamoff offset, std::ios_base::seekdir origin) {
190 assert(!tempo.empty());
191
192 if (offset == 0 && origin == std::ios_base::beg) {
193 mtime = seq->rewind_to_loop()->time;
194 reset_tempos_after_loop();
195
196 // When the loop points to the end of the track keep it alive to match
197 // RPG_RT behaviour.
198 loops_to_end = mtime >= seq->get_total_time();
199
200 if (!mididec->SupportsMidiMessages()) {
201 mididec->Seek(tempo.back().GetSamples(loops_to_end ? seq->get_total_time() : mtime), origin);
202 }
203
204 return true;
205 }
206
207 return false;
208 }
209
IsFinished() const210 bool AudioDecoderMidi::IsFinished() const {
211 if (loops_to_end) {
212 return false;
213 }
214
215 return seq->is_at_end();
216 }
217
Update(std::chrono::microseconds delta)218 void AudioDecoderMidi::Update(std::chrono::microseconds delta) {
219 if (paused) {
220 return;
221 }
222 if (fade_steps >= 0 && mtime - last_fade_mtime > 0.1s) {
223 volume = Utils::Clamp<float>(volume + delta_volume_step, 0.0f, 1.0f);
224 if (!mididec->SupportsMidiMessages()) {
225 log_volume = AdjustVolume(volume * 100.0f);
226 }
227 for (int i = 0; i < 16; i++) {
228 uint32_t msg = midimsg_volume(i, static_cast<uint8_t>(channel_volumes[i] * volume));
229 mididec->SendMidiMessage(msg);
230 }
231 last_fade_mtime = mtime;
232 fade_steps -= 1;
233 }
234 }
235
UpdateMidi(std::chrono::microseconds delta)236 void AudioDecoderMidi::UpdateMidi(std::chrono::microseconds delta) {
237 if (paused) {
238 return;
239 }
240
241 mtime += std::chrono::microseconds(static_cast<int>(delta.count() * pitch / 100));
242 Update(delta);
243 seq->play(mtime, this);
244
245 if (IsFinished() && looping) {
246 mtime = seq->rewind_to_loop()->time;
247 reset_tempos_after_loop();
248 loop_count += 1;
249 }
250 }
251
GetFormat(int & freq,AudioDecoderBase::Format & format,int & channels) const252 void AudioDecoderMidi::GetFormat(int& freq, AudioDecoderBase::Format& format, int& channels) const {
253 mididec->GetFormat(freq, format, channels);
254 }
255
SetFormat(int freq,AudioDecoderBase::Format format,int channels)256 bool AudioDecoderMidi::SetFormat(int freq, AudioDecoderBase::Format format, int channels) {
257 frequency = freq;
258 return mididec->SetFormat(freq, format, channels);
259 }
260
SetPitch(int pitch)261 bool AudioDecoderMidi::SetPitch(int pitch) {
262 if (!mididec->SupportsMidiMessages()) {
263 if (!mididec->SetPitch(pitch)) {
264 this->pitch = 100;
265 return false;
266 }
267 }
268
269 this->pitch = pitch;
270 return true;
271 }
272
GetTicks() const273 int AudioDecoderMidi::GetTicks() const {
274 assert(!tempo.empty());
275
276 return tempo.back().GetTicks(mtime);
277 }
278
Reset()279 void AudioDecoderMidi::Reset() {
280 // Generate a MIDI reset event so the device doesn't
281 // leave notes playing or keeps any state
282 reset();
283 }
284
FillBuffer(uint8_t * buffer,int length)285 int AudioDecoderMidi::FillBuffer(uint8_t* buffer, int length) {
286 if (loops_to_end) {
287 memset(buffer, '\0', length);
288 return length;
289 }
290
291 if (!mididec->SupportsMidiMessages()) {
292 // Fast path for WildMidi as it does not care about messages
293 float delta = (float)(length / bytes_per_sample) / (frequency * 100.0f / pitch);
294 mtime += std::chrono::microseconds(static_cast<int>(delta * 1'000'000));
295 seq->play(mtime, this);
296 return mididec->FillBuffer(buffer, length);
297 }
298
299 int samples_max = length / bytes_per_sample;
300 int written = 0;
301
302 // Advance the MIDI playback in smaller steps to achieve a good message resolution
303 // Otherwise the MIDI sounds off because messages are processed too late.
304 while (samples_max > 0) {
305 // Process MIDI messages
306 size_t samples = std::min(samples_per_play, samples_max);
307 float delta = (float)samples / (frequency * 100.0f / pitch);
308 mtime += std::chrono::microseconds(static_cast<int>(delta * 1'000'000));
309 seq->play(mtime, this);
310
311 // Write audio samples
312 int len = samples * bytes_per_sample;
313 int res = mididec->FillBuffer(buffer + written, len);
314 written += res;
315
316 if (samples < samples_per_play || res < len) {
317 // Done
318 break;
319 }
320
321 samples_max -= samples;
322 }
323
324 return written;
325 }
326
SendMessageToAllChannels(uint32_t midi_msg)327 void AudioDecoderMidi::SendMessageToAllChannels(uint32_t midi_msg) {
328 for (int channel = 0; channel < 16; channel++) {
329 midi_msg &= ~(0xF);
330 midi_msg |= (channel & 0x0F);
331 mididec->SendMidiMessage(midi_msg);
332 }
333 }
334
midi_message(int,uint_least32_t message)335 void AudioDecoderMidi::midi_message(int, uint_least32_t message) {
336 uint8_t event_type = midimsg_get_event_type(message);
337 uint8_t channel = midimsg_get_channel(message);
338 uint8_t value1 = midimsg_get_value1(message);
339 uint8_t value2 = midimsg_get_value2(message);
340
341 if (event_type == midi_event_control_change && value1 == midi_control_volume) {
342 // Adjust channel volume
343 channel_volumes[channel] = value2;
344 // Send the modified volume to midiout
345 message = midimsg_volume(channel, static_cast<uint8_t>(value2 * volume));
346 }
347 mididec->SendMidiMessage(message);
348 }
349
sysex_message(int,const void * data,std::size_t size)350 void AudioDecoderMidi::sysex_message(int, const void* data, std::size_t size) {
351 mididec->SendSysExMessage(reinterpret_cast<const uint8_t*>(data), size);
352 }
353
meta_event(int event,const void * data,std::size_t size)354 void AudioDecoderMidi::meta_event(int event, const void* data, std::size_t size) {
355 // Meta events are never sent over MIDI ports.
356 assert(!tempo.empty());
357 const auto* d = reinterpret_cast<const uint8_t*>(data);
358 if (size == 3 && event == 0x51) {
359 uint32_t new_tempo = (static_cast<uint32_t>(static_cast<unsigned char>(d[0])) << 16)
360 | (static_cast<unsigned char>(d[1]) << 8)
361 | static_cast<unsigned char>(d[2]);
362 tempo.emplace_back(this, new_tempo, &tempo.back());
363 }
364 }
365
reset()366 void AudioDecoderMidi::reset() {
367 // MIDI reset event
368 SendMessageToAllChannels(midimsg_all_sound_off(0));
369 SendMessageToAllChannels(midimsg_reset_all_controller(0));
370 mididec->SendMidiReset();
371 }
372
reset_tempos_after_loop()373 void AudioDecoderMidi::reset_tempos_after_loop() {
374 if (mtime > 0us) {
375 // Throw away all tempo data after the loop point
376 auto rit = std::find_if(tempo.rbegin(), tempo.rend(), [&](auto& t) { return t.mtime <= mtime; });
377 auto it = rit.base();
378 if (it != tempo.end()) {
379 tempo.erase(it, tempo.end());
380 }
381 } else {
382 tempo.clear();
383 tempo.emplace_back(this, midi_default_tempo);
384 }
385 }
386
MidiTempoData(const AudioDecoderMidi * midi,uint32_t cur_tempo,const MidiTempoData * prev)387 AudioDecoderMidi::MidiTempoData::MidiTempoData(const AudioDecoderMidi* midi, uint32_t cur_tempo, const MidiTempoData* prev)
388 : tempo(cur_tempo) {
389 ticks_per_us = (float)midi->seq->get_division() / tempo;
390 samples_per_tick = midi->frequency * 1 / (ticks_per_us * 1000000);
391 mtime = midi->mtime;
392 if (prev) {
393 std::chrono::microseconds delta = mtime - prev->mtime;
394 int ticks_since_last = static_cast<int>(ticks_per_us * delta.count());
395 ticks = prev->ticks + ticks_since_last;
396 samples = prev->samples + ticks_since_last * samples_per_tick;
397 }
398 }
399
GetTicks(std::chrono::microseconds mtime_cur) const400 int AudioDecoderMidi::MidiTempoData::GetTicks(std::chrono::microseconds mtime_cur) const {
401 std::chrono::microseconds delta = mtime_cur - mtime;
402 return ticks + static_cast<int>(ticks_per_us * delta.count());
403 }
404
GetSamples(std::chrono::microseconds mtime_cur) const405 int AudioDecoderMidi::MidiTempoData::GetSamples(std::chrono::microseconds mtime_cur) const {
406 std::chrono::microseconds delta = mtime_cur - mtime;
407 int ticks_since_last = static_cast<int>(ticks_per_us * delta.count());
408 return samples + static_cast<int>(ticks_since_last * samples_per_tick);
409 }
410