aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi_midiplay.cpp3
-rw-r--r--src/adlmidi_midiplay.hpp13
-rw-r--r--src/adlmidi_sequencer.cpp10
-rw-r--r--src/midi_sequencer.h6
-rw-r--r--src/midi_sequencer.hpp17
-rw-r--r--src/midi_sequencer_impl.hpp18
6 files changed, 51 insertions, 16 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 358e284..a7fb4ed 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -187,6 +187,7 @@ void MIDIplay::partialReset()
synth.reset(m_setup.emulator, m_setup.PCM_RATE, this);
m_chipChannels.clear();
m_chipChannels.resize((size_t)synth.m_numChannels);
+ resetMIDIDefaults();
}
void MIDIplay::resetMIDI()
@@ -774,7 +775,7 @@ void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value)
break;
case 121: // Reset all controllers
- m_midiChannels[channel].resetAllControllers();
+ m_midiChannels[channel].resetAllControllers121();
noteUpdateAll(channel, Upd_Pan + Upd_Volume + Upd_Pitch);
// Kill all sustained notes
killSustainingNotes(channel, -1, AdlChannel::LocationData::Sustain_ANY);
diff --git a/src/adlmidi_midiplay.hpp b/src/adlmidi_midiplay.hpp
index 93b36e9..7eaf51d 100644
--- a/src/adlmidi_midiplay.hpp
+++ b/src/adlmidi_midiplay.hpp
@@ -327,11 +327,21 @@ public:
*/
void resetAllControllers()
{
+ volume = def_volume;
+ brightness = 127;
+
+ resetAllControllers121();
+ }
+
+ /**
+ * @brief Reset all MIDI controllers into initial state (CC121)
+ */
+ void resetAllControllers121()
+ {
bend = 0;
bendsense_msb = def_bendsense_msb;
bendsense_lsb = def_bendsense_lsb;
updateBendSensitivity();
- volume = def_volume;
expression = 127;
sustain = false;
softPedal = false;
@@ -347,7 +357,6 @@ public:
portamentoEnable = false;
portamentoSource = -1;
portamentoRate = HUGE_VAL;
- brightness = 127;
}
/**
diff --git a/src/adlmidi_sequencer.cpp b/src/adlmidi_sequencer.cpp
index e6de2b3..bf3d86c 100644
--- a/src/adlmidi_sequencer.cpp
+++ b/src/adlmidi_sequencer.cpp
@@ -103,6 +103,13 @@ static size_t rtCurrentDevice(void *userdata, size_t track)
MIDIplay *context = reinterpret_cast<MIDIplay *>(userdata);
return context->realTime_currentDevice(track);
}
+
+static void rtSongBegin(void *userdata)
+{
+ MIDIplay *context = reinterpret_cast<MIDIplay *>(userdata);
+ return context->realTime_ResetState();
+}
+
/* NonStandard calls End */
@@ -131,6 +138,9 @@ void MIDIplay::initSequencerInterface()
seq->rt_rawOPL = rtRawOPL;
seq->rt_deviceSwitch = rtDeviceSwitch;
seq->rt_currentDevice = rtCurrentDevice;
+
+ seq->onSongStart = rtSongBegin;
+ seq->onSongStart_userData = this;
/* NonStandard calls End */
m_sequencer->setInterface(seq);
diff --git a/src/midi_sequencer.h b/src/midi_sequencer.h
index b9b8982..4d35d06 100644
--- a/src/midi_sequencer.h
+++ b/src/midi_sequencer.h
@@ -79,6 +79,12 @@ typedef struct BW_MidiRtInterface
/*! User data which will be passed through On-LoopStart hook */
void *onloopEnd_userData;
+ typedef void (*SongStartHook)(void *userdata);
+ /*! Song start hook which is calling when starting playing song at begin */
+ SongStartHook onSongStart;
+ /*! User data which will be passed through On-SongStart hook */
+ void *onSongStart_userData;
+
/*! MIDI Run Time event calls user data */
void *rtUserData;
diff --git a/src/midi_sequencer.hpp b/src/midi_sequencer.hpp
index 7ff864c..69dead8 100644
--- a/src/midi_sequencer.hpp
+++ b/src/midi_sequencer.hpp
@@ -76,7 +76,7 @@ class BW_MidiSequencer
//! System Exclusive message, type 2
T_SYSEX2 = 0xF7,//size == len
//! Special event
- T_SPECIAL = 0xFF
+ T_SPECIAL = 0xFF,
};
/**
* @brief Special MIDI event sub-types
@@ -132,18 +132,21 @@ class BW_MidiSequencer
//! [Non-Standard] Loop End point with support of multi-loops
ST_LOOPSTACK_BREAK = 0xE6,//size == 0 <CUSTOM>
//! [Non-Standard] Callback Trigger
- ST_CALLBACK_TRIGGER = 0xE7//size == 1 <CUSTOM>
+ ST_CALLBACK_TRIGGER = 0xE7,//size == 1 <CUSTOM>
+
+ // Built-in hooks
+ ST_SONG_BEGIN_HOOK = 0x101
};
//! Main type of event
- uint8_t type;
+ uint_fast16_t type;
//! Sub-type of the event
- uint8_t subtype;
+ uint_fast16_t subtype;
//! Targeted MIDI channel
- uint8_t channel;
+ uint_fast16_t channel;
//! Is valid event
- uint8_t isValid;
+ uint_fast16_t isValid;
//! Reserved 5 bytes padding
- uint8_t __padding[4];
+ uint_fast16_t __padding[4];
//! Absolute tick position (Used for the tempo calculation only)
uint64_t absPosition;
//! Raw data of this event
diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp
index f0ba839..62e78c3 100644
--- a/src/midi_sequencer_impl.hpp
+++ b/src/midi_sequencer_impl.hpp
@@ -206,6 +206,7 @@ void BW_MidiSequencer::MidiTrackRow::sortEvents(bool *noteStates)
else if((events[i].type == MidiEvent::T_SPECIAL) && (
(events[i].subtype == MidiEvent::ST_MARKER) ||
(events[i].subtype == MidiEvent::ST_DEVICESWITCH) ||
+ (events[i].subtype == MidiEvent::ST_SONG_BEGIN_HOOK) ||
(events[i].subtype == MidiEvent::ST_LOOPSTART) ||
(events[i].subtype == MidiEvent::ST_LOOPEND) ||
(events[i].subtype == MidiEvent::ST_LOOPSTACK_BEGIN) ||
@@ -566,13 +567,11 @@ bool BW_MidiSequencer::buildSmfTrackData(const std::vector<std::vector<uint8_t>
}
// HACK: Begin every track with "Reset all controllers" event to avoid controllers state break came from end of song
- for(uint8_t chan = 0; chan < 16; chan++)
+ if(tk == 0)
{
MidiEvent resetEvent;
- resetEvent.type = MidiEvent::T_CTRLCHANGE;
- resetEvent.channel = chan;
- resetEvent.data.push_back(121);
- resetEvent.data.push_back(0);
+ resetEvent.type = MidiEvent::T_SPECIAL;
+ resetEvent.subtype = MidiEvent::ST_SONG_BEGIN_HOOK;
evtPos.events.push_back(resetEvent);
}
@@ -1677,7 +1676,7 @@ void BW_MidiSequencer::handleEvent(size_t track, const BW_MidiSequencer::MidiEve
if(evt.type == MidiEvent::T_SPECIAL)
{
// Special event FF
- uint8_t evtype = evt.subtype;
+ uint_fast16_t evtype = evt.subtype;
uint64_t length = static_cast<uint64_t>(evt.data.size());
const char *data(length ? reinterpret_cast<const char *>(evt.data.data()) : "");
@@ -1771,6 +1770,13 @@ void BW_MidiSequencer::handleEvent(size_t track, const BW_MidiSequencer::MidiEve
return;
}
+ if(evtype == MidiEvent::ST_SONG_BEGIN_HOOK)
+ {
+ if(m_interface->onSongStart)
+ m_interface->onSongStart(m_interface->onSongStart_userData);
+ return;
+ }
+
return;
}