mirror of https://github.com/AxioDL/amuse.git
commit
95ffcc2d16
|
@ -45,7 +45,7 @@ class Sequencer : public Entity {
|
||||||
/** State of a single MIDI channel */
|
/** State of a single MIDI channel */
|
||||||
struct ChannelState {
|
struct ChannelState {
|
||||||
Sequencer* m_parent = nullptr;
|
Sequencer* m_parent = nullptr;
|
||||||
uint8_t m_chanId;
|
uint8_t m_chanId = 0;
|
||||||
const SongGroupIndex::MIDISetup* m_setup = nullptr; /* Channel defaults to program 0 if null */
|
const SongGroupIndex::MIDISetup* m_setup = nullptr; /* Channel defaults to program 0 if null */
|
||||||
const SongGroupIndex::PageEntry* m_page = nullptr;
|
const SongGroupIndex::PageEntry* m_page = nullptr;
|
||||||
~ChannelState();
|
~ChannelState();
|
||||||
|
@ -57,14 +57,14 @@ class Sequencer : public Entity {
|
||||||
std::unordered_map<uint8_t, ObjToken<Voice>> m_chanVoxs;
|
std::unordered_map<uint8_t, ObjToken<Voice>> m_chanVoxs;
|
||||||
std::unordered_set<ObjToken<Voice>> m_keyoffVoxs;
|
std::unordered_set<ObjToken<Voice>> m_keyoffVoxs;
|
||||||
ObjToken<Voice> m_lastVoice;
|
ObjToken<Voice> m_lastVoice;
|
||||||
int8_t m_ctrlVals[128] = {}; /**< MIDI controller values */
|
std::array<int8_t, 128> m_ctrlVals{}; /**< MIDI controller values */
|
||||||
float m_curPitchWheel = 0.f; /**< MIDI pitch-wheel */
|
float m_curPitchWheel = 0.f; /**< MIDI pitch-wheel */
|
||||||
int8_t m_pitchWheelRange = -1; /**< Pitch wheel range settable by RPN 0 */
|
int8_t m_pitchWheelRange = -1; /**< Pitch wheel range settable by RPN 0 */
|
||||||
int8_t m_curProgram = 0; /**< MIDI program number */
|
int8_t m_curProgram = 0; /**< MIDI program number */
|
||||||
float m_curVol = 1.f; /**< Current volume of channel */
|
float m_curVol = 1.f; /**< Current volume of channel */
|
||||||
float m_curPan = 0.f; /**< Current panning of channel */
|
float m_curPan = 0.f; /**< Current panning of channel */
|
||||||
uint16_t m_rpn = 0; /**< Current RPN (only pitch-range 0x0000 supported) */
|
uint16_t m_rpn = 0; /**< Current RPN (only pitch-range 0x0000 supported) */
|
||||||
double m_ticksPerSec = 1000.0; /**< Current ticks per second (tempo) for channel */
|
double m_ticksPerSec = 1000.0; /**< Current ticks per second (tempo) for channel */
|
||||||
|
|
||||||
void _bringOutYourDead();
|
void _bringOutYourDead();
|
||||||
size_t getVoiceCount() const;
|
size_t getVoiceCount() const;
|
||||||
|
|
|
@ -53,7 +53,7 @@ Sequencer::~Sequencer() {
|
||||||
|
|
||||||
Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, const SongGroupIndex* songGroup,
|
Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, const SongGroupIndex* songGroup,
|
||||||
SongId setupId, ObjToken<Studio> studio)
|
SongId setupId, ObjToken<Studio> studio)
|
||||||
: Entity(engine, group, groupId), m_songGroup(songGroup), m_studio(studio) {
|
: Entity(engine, group, groupId), m_songGroup(songGroup), m_studio(std::move(studio)) {
|
||||||
auto it = m_songGroup->m_midiSetups.find(setupId);
|
auto it = m_songGroup->m_midiSetups.find(setupId);
|
||||||
if (it != m_songGroup->m_midiSetups.cend())
|
if (it != m_songGroup->m_midiSetups.cend())
|
||||||
m_midiSetup = it->second.data();
|
m_midiSetup = it->second.data();
|
||||||
|
@ -61,7 +61,7 @@ Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, c
|
||||||
|
|
||||||
Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, const SFXGroupIndex* sfxGroup,
|
Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, const SFXGroupIndex* sfxGroup,
|
||||||
ObjToken<Studio> studio)
|
ObjToken<Studio> studio)
|
||||||
: Entity(engine, group, groupId), m_sfxGroup(sfxGroup), m_studio(studio) {
|
: Entity(engine, group, groupId), m_sfxGroup(sfxGroup), m_studio(std::move(studio)) {
|
||||||
std::map<ObjectId, const SFXGroupIndex::SFXEntry*> sortSFX;
|
std::map<ObjectId, const SFXGroupIndex::SFXEntry*> sortSFX;
|
||||||
for (const auto& sfx : sfxGroup->m_sfxEntries)
|
for (const auto& sfx : sfxGroup->m_sfxEntries)
|
||||||
sortSFX[sfx.first] = &sfx.second;
|
sortSFX[sfx.first] = &sfx.second;
|
||||||
|
@ -71,7 +71,7 @@ Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, c
|
||||||
m_sfxMappings.push_back(sfx.second);
|
m_sfxMappings.push_back(sfx.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sequencer::ChannelState::~ChannelState() {}
|
Sequencer::ChannelState::~ChannelState() = default;
|
||||||
|
|
||||||
Sequencer::ChannelState::ChannelState(Sequencer& parent, uint8_t chanId) : m_parent(&parent), m_chanId(chanId) {
|
Sequencer::ChannelState::ChannelState(Sequencer& parent, uint8_t chanId) : m_parent(&parent), m_chanId(chanId) {
|
||||||
if (m_parent->m_songGroup) {
|
if (m_parent->m_songGroup) {
|
||||||
|
@ -208,7 +208,7 @@ ObjToken<Voice> Sequencer::ChannelState::keyOn(uint8_t note, uint8_t velocity) {
|
||||||
if (*ret) {
|
if (*ret) {
|
||||||
(*ret)->m_sequencer = m_parent;
|
(*ret)->m_sequencer = m_parent;
|
||||||
m_chanVoxs[note] = *ret;
|
m_chanVoxs[note] = *ret;
|
||||||
(*ret)->installCtrlValues(m_ctrlVals);
|
(*ret)->installCtrlValues(m_ctrlVals.data());
|
||||||
|
|
||||||
ObjectId oid;
|
ObjectId oid;
|
||||||
bool res;
|
bool res;
|
||||||
|
@ -246,11 +246,13 @@ ObjToken<Voice> Sequencer::ChannelState::keyOn(uint8_t note, uint8_t velocity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjToken<Voice> Sequencer::keyOn(uint8_t chan, uint8_t note, uint8_t velocity) {
|
ObjToken<Voice> Sequencer::keyOn(uint8_t chan, uint8_t note, uint8_t velocity) {
|
||||||
if (chan > 15)
|
if (chan >= m_chanStates.size()) {
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_chanStates[chan])
|
if (!m_chanStates[chan]) {
|
||||||
m_chanStates[chan] = ChannelState(*this, chan);
|
m_chanStates[chan] = ChannelState(*this, chan);
|
||||||
|
}
|
||||||
|
|
||||||
return m_chanStates[chan].keyOn(note, velocity);
|
return m_chanStates[chan].keyOn(note, velocity);
|
||||||
}
|
}
|
||||||
|
@ -268,8 +270,9 @@ void Sequencer::ChannelState::keyOff(uint8_t note, uint8_t velocity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequencer::keyOff(uint8_t chan, uint8_t note, uint8_t velocity) {
|
void Sequencer::keyOff(uint8_t chan, uint8_t note, uint8_t velocity) {
|
||||||
if (chan > 15 || !m_chanStates[chan])
|
if (chan >= m_chanStates.size() || !m_chanStates[chan]) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_chanStates[chan].keyOff(note, velocity);
|
m_chanStates[chan].keyOff(note, velocity);
|
||||||
}
|
}
|
||||||
|
@ -351,8 +354,9 @@ void Sequencer::ChannelState::prevProgram() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequencer::setCtrlValue(uint8_t chan, uint8_t ctrl, int8_t val) {
|
void Sequencer::setCtrlValue(uint8_t chan, uint8_t ctrl, int8_t val) {
|
||||||
if (chan > 15)
|
if (chan >= m_chanStates.size()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctrl == 0x66) {
|
if (ctrl == 0x66) {
|
||||||
fmt::print(fmt("Loop Start\n"));
|
fmt::print(fmt("Loop Start\n"));
|
||||||
|
@ -360,8 +364,9 @@ void Sequencer::setCtrlValue(uint8_t chan, uint8_t ctrl, int8_t val) {
|
||||||
fmt::print(fmt("Loop End\n"));
|
fmt::print(fmt("Loop End\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_chanStates[chan])
|
if (!m_chanStates[chan]) {
|
||||||
m_chanStates[chan] = ChannelState(*this, chan);
|
m_chanStates[chan] = ChannelState(*this, chan);
|
||||||
|
}
|
||||||
|
|
||||||
m_chanStates[chan].setCtrlValue(ctrl, val);
|
m_chanStates[chan].setCtrlValue(ctrl, val);
|
||||||
}
|
}
|
||||||
|
@ -375,11 +380,13 @@ void Sequencer::ChannelState::setPitchWheel(float pitchWheel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequencer::setPitchWheel(uint8_t chan, float pitchWheel) {
|
void Sequencer::setPitchWheel(uint8_t chan, float pitchWheel) {
|
||||||
if (chan > 15)
|
if (chan >= m_chanStates.size()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_chanStates[chan])
|
if (!m_chanStates[chan]) {
|
||||||
m_chanStates[chan] = ChannelState(*this, chan);
|
m_chanStates[chan] = ChannelState(*this, chan);
|
||||||
|
}
|
||||||
|
|
||||||
m_chanStates[chan].setPitchWheel(pitchWheel);
|
m_chanStates[chan].setPitchWheel(pitchWheel);
|
||||||
}
|
}
|
||||||
|
@ -422,18 +429,22 @@ void Sequencer::allOff(bool now) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequencer::allOff(uint8_t chan, bool now) {
|
void Sequencer::allOff(uint8_t chan, bool now) {
|
||||||
if (chan > 15 || !m_chanStates[chan])
|
if (chan >= m_chanStates.size() || !m_chanStates[chan]) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (now) {
|
if (now) {
|
||||||
for (const auto& vox : m_chanStates[chan].m_chanVoxs)
|
for (const auto& vox : m_chanStates[chan].m_chanVoxs) {
|
||||||
vox.second->kill();
|
vox.second->kill();
|
||||||
for (const auto& vox : m_chanStates[chan].m_keyoffVoxs)
|
}
|
||||||
|
for (const auto& vox : m_chanStates[chan].m_keyoffVoxs) {
|
||||||
vox->kill();
|
vox->kill();
|
||||||
|
}
|
||||||
m_chanStates[chan].m_chanVoxs.clear();
|
m_chanStates[chan].m_chanVoxs.clear();
|
||||||
m_chanStates[chan].m_keyoffVoxs.clear();
|
m_chanStates[chan].m_keyoffVoxs.clear();
|
||||||
} else
|
} else {
|
||||||
m_chanStates[chan].allOff();
|
m_chanStates[chan].allOff();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequencer::ChannelState::killKeygroup(uint8_t kg, bool now) {
|
void Sequencer::ChannelState::killKeygroup(uint8_t kg, bool now) {
|
||||||
|
@ -575,12 +586,14 @@ void Sequencer::setVolume(float vol, float fadeTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t Sequencer::getChanProgram(int8_t chanId) const {
|
int8_t Sequencer::getChanProgram(int8_t chanId) const {
|
||||||
if (chanId > 15)
|
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_chanStates[chanId]) {
|
if (!m_chanStates[chanId]) {
|
||||||
if (!m_midiSetup)
|
if (!m_midiSetup) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
return m_midiSetup[chanId].programNo;
|
return m_midiSetup[chanId].programNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,31 +601,37 @@ int8_t Sequencer::getChanProgram(int8_t chanId) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sequencer::setChanProgram(int8_t chanId, int8_t prog) {
|
bool Sequencer::setChanProgram(int8_t chanId, int8_t prog) {
|
||||||
if (chanId > 15)
|
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_chanStates[chanId])
|
if (!m_chanStates[chanId]) {
|
||||||
m_chanStates[chanId] = ChannelState(*this, chanId);
|
m_chanStates[chanId] = ChannelState(*this, chanId);
|
||||||
|
}
|
||||||
|
|
||||||
return m_chanStates[chanId].programChange(prog);
|
return m_chanStates[chanId].programChange(prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequencer::nextChanProgram(int8_t chanId) {
|
void Sequencer::nextChanProgram(int8_t chanId) {
|
||||||
if (chanId > 15)
|
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_chanStates[chanId])
|
if (!m_chanStates[chanId]) {
|
||||||
m_chanStates[chanId] = ChannelState(*this, chanId);
|
m_chanStates[chanId] = ChannelState(*this, chanId);
|
||||||
|
}
|
||||||
|
|
||||||
return m_chanStates[chanId].nextProgram();
|
return m_chanStates[chanId].nextProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequencer::prevChanProgram(int8_t chanId) {
|
void Sequencer::prevChanProgram(int8_t chanId) {
|
||||||
if (chanId > 15)
|
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_chanStates[chanId])
|
if (!m_chanStates[chanId]) {
|
||||||
m_chanStates[chanId] = ChannelState(*this, chanId);
|
m_chanStates[chanId] = ChannelState(*this, chanId);
|
||||||
|
}
|
||||||
|
|
||||||
return m_chanStates[chanId].prevProgram();
|
return m_chanStates[chanId].prevProgram();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue