mirror of https://github.com/AxioDL/amuse.git
Envelope command fixes, 20ms default envelope
This commit is contained in:
parent
d5b50e3633
commit
0c8d8f571c
283
driver/main.cpp
283
driver/main.cpp
|
@ -80,13 +80,14 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
int8_t m_lastChanProg = -1;
|
int8_t m_lastChanProg = -1;
|
||||||
|
|
||||||
/* Control state */
|
/* Control state */
|
||||||
float m_volume = 0.8f;
|
float m_volume = 0.5f;
|
||||||
float m_modulation = 0.f;
|
float m_modulation = 0.f;
|
||||||
float m_pitchBend = 0.f;
|
float m_pitchBend = 0.f;
|
||||||
bool m_updateDisp = false;
|
bool m_updateDisp = false;
|
||||||
bool m_running = true;
|
bool m_running = true;
|
||||||
bool m_wantsNext = false;
|
bool m_wantsNext = false;
|
||||||
bool m_wantsPrev = false;
|
bool m_wantsPrev = false;
|
||||||
|
bool m_breakout = false;
|
||||||
int m_panicCount = 0;
|
int m_panicCount = 0;
|
||||||
|
|
||||||
void UpdateSongDisplay()
|
void UpdateSongDisplay()
|
||||||
|
@ -219,6 +220,14 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
UpdateSongDisplay();
|
UpdateSongDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_breakout)
|
||||||
|
{
|
||||||
|
m_breakout = false;
|
||||||
|
m_seq->allOff(true);
|
||||||
|
m_seq.reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_win->waitForRetrace();
|
m_win->waitForRetrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,6 +307,13 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
UpdateSFXDisplay();
|
UpdateSFXDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_breakout)
|
||||||
|
{
|
||||||
|
m_breakout = false;
|
||||||
|
m_vox.reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_win->waitForRetrace();
|
m_win->waitForRetrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,148 +620,161 @@ struct AppCallback : boo::IApplicationCallback
|
||||||
allSFXGroups[it->first] = std::make_pair(&grp, &it->second);
|
allSFXGroups[it->first] = std::make_pair(&grp, &it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt loading song */
|
while (m_running)
|
||||||
std::vector<std::pair<std::string, amuse::ContainerRegistry::SongData>> songs;
|
|
||||||
if (m_argc > 2)
|
|
||||||
{
|
{
|
||||||
songs = amuse::ContainerRegistry::LoadSongs(m_argv[2]);
|
m_groupId = -1;
|
||||||
|
m_setupId = -1;
|
||||||
|
|
||||||
/* Get song selection from user */
|
/* Attempt loading song */
|
||||||
if (songs.size() > 1)
|
std::vector<std::pair<std::string, amuse::ContainerRegistry::SongData>> songs;
|
||||||
|
if (m_argc > 2)
|
||||||
{
|
{
|
||||||
/* Ask user to specify which song */
|
#if _WIN32
|
||||||
printf("Multiple Songs discovered:\n");
|
char utf8Path[1024];
|
||||||
int idx = 0;
|
WideCharToMultiByte(CP_UTF8, 0, m_argv[2], -1, utf8Path, 1024, nullptr, nullptr);
|
||||||
for (const auto& pair : songs)
|
#else
|
||||||
|
const char* utf8Path = m_argv[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
songs = amuse::ContainerRegistry::LoadSongs(utf8Path);
|
||||||
|
|
||||||
|
/* Get song selection from user */
|
||||||
|
if (songs.size() > 1)
|
||||||
{
|
{
|
||||||
printf(" %d %s (Group %d, Setup %d)\n", idx++,
|
/* Ask user to specify which song */
|
||||||
pair.first.c_str(), pair.second.m_groupId, pair.second.m_setupId);
|
printf("Multiple Songs discovered:\n");
|
||||||
|
int idx = 0;
|
||||||
|
for (const auto& pair : songs)
|
||||||
|
{
|
||||||
|
printf(" %d %s (Group %d, Setup %d)\n", idx++,
|
||||||
|
pair.first.c_str(), pair.second.m_groupId, pair.second.m_setupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
int userSel = 0;
|
||||||
|
printf("Enter Song Number: ");
|
||||||
|
if (scanf("%d", &userSel) <= 0)
|
||||||
|
Log.report(logvisor::Fatal, "unable to parse prompt");
|
||||||
|
|
||||||
|
if (userSel < songs.size())
|
||||||
|
{
|
||||||
|
m_arrData = &songs[userSel].second;
|
||||||
|
m_groupId = m_arrData->m_groupId;
|
||||||
|
m_setupId = m_arrData->m_setupId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.report(logvisor::Fatal, "unable to find Song %d", userSel);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
int userSel = 0;
|
|
||||||
printf("Enter Song Number: ");
|
|
||||||
if (scanf("%d", &userSel) <= 0)
|
|
||||||
Log.report(logvisor::Fatal, "unable to parse prompt");
|
|
||||||
|
|
||||||
if (userSel < songs.size())
|
|
||||||
{
|
{
|
||||||
m_arrData = &songs[userSel].second;
|
m_arrData = &songs[0].second;
|
||||||
m_groupId = m_arrData->m_groupId;
|
m_groupId = m_arrData->m_groupId;
|
||||||
m_setupId = m_arrData->m_setupId;
|
m_setupId = m_arrData->m_setupId;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get group selection from user */
|
||||||
|
if (m_groupId != -1)
|
||||||
|
{
|
||||||
|
if (allSongGroups.find(m_groupId) != allSongGroups.end())
|
||||||
|
m_sfxGroup = false;
|
||||||
|
else if (allSFXGroups.find(m_groupId) != allSFXGroups.end())
|
||||||
|
m_sfxGroup = true;
|
||||||
else
|
else
|
||||||
Log.report(logvisor::Fatal, "unable to find Song %d", userSel);
|
Log.report(logvisor::Fatal, "unable to find Group %d", m_groupId);
|
||||||
|
}
|
||||||
|
else if (totalGroups > 1)
|
||||||
|
{
|
||||||
|
/* Ask user to specify which group in project */
|
||||||
|
printf("Multiple Audio Groups discovered:\n");
|
||||||
|
for (const auto& pair : allSFXGroups)
|
||||||
|
{
|
||||||
|
printf(" %d %s (SFXGroup) %" PRISize " sfx-entries\n",
|
||||||
|
pair.first, pair.second.first->first.c_str(),
|
||||||
|
pair.second.second->m_sfxEntries.size());
|
||||||
|
}
|
||||||
|
for (const auto& pair : allSongGroups)
|
||||||
|
{
|
||||||
|
printf(" %d %s (SongGroup) %" PRISize " normal-pages, %" PRISize " drum-pages\n",
|
||||||
|
pair.first, pair.second.first->first.c_str(),
|
||||||
|
pair.second.second->m_normPages.size(), pair.second.second->m_drumPages.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int userSel = 0;
|
||||||
|
printf("Enter Group Number: ");
|
||||||
|
if (scanf("%d", &userSel) <= 0)
|
||||||
|
Log.report(logvisor::Fatal, "unable to parse prompt");
|
||||||
|
|
||||||
|
if (allSongGroups.find(userSel) != allSongGroups.end())
|
||||||
|
{
|
||||||
|
m_groupId = userSel;
|
||||||
|
m_sfxGroup = false;
|
||||||
|
}
|
||||||
|
else if (allSFXGroups.find(userSel) != allSFXGroups.end())
|
||||||
|
{
|
||||||
|
m_groupId = userSel;
|
||||||
|
m_sfxGroup = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.report(logvisor::Fatal, "unable to find Group %d", userSel);
|
||||||
|
}
|
||||||
|
else if (totalGroups == 1)
|
||||||
|
{
|
||||||
|
/* Load one and only group */
|
||||||
|
if (allSongGroups.size())
|
||||||
|
{
|
||||||
|
const auto& pair = *allSongGroups.cbegin();
|
||||||
|
m_groupId = pair.first;
|
||||||
|
m_sfxGroup = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto& pair = *allSFXGroups.cbegin();
|
||||||
|
m_groupId = pair.first;
|
||||||
|
m_sfxGroup = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.report(logvisor::Fatal, "empty project");
|
||||||
|
|
||||||
|
/* Make final group selection */
|
||||||
|
amuse::IntrusiveAudioGroupData* selData = nullptr;
|
||||||
|
const amuse::SongGroupIndex* songIndex = nullptr;
|
||||||
|
const amuse::SFXGroupIndex* sfxIndex = nullptr;
|
||||||
|
auto songSearch = allSongGroups.find(m_groupId);
|
||||||
|
if (songSearch != allSongGroups.end())
|
||||||
|
{
|
||||||
|
selData = &songSearch->second.first->second;
|
||||||
|
songIndex = songSearch->second.second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_arrData = &songs[0].second;
|
auto sfxSearch = allSFXGroups.find(m_groupId);
|
||||||
m_groupId = m_arrData->m_groupId;
|
if (sfxSearch != allSFXGroups.end())
|
||||||
m_setupId = m_arrData->m_setupId;
|
{
|
||||||
|
selData = &sfxSearch->second.first->second;
|
||||||
|
sfxIndex = sfxSearch->second.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Get group selection from user */
|
if (!selData)
|
||||||
if (m_groupId != -1)
|
Log.report(logvisor::Fatal, "unable to select audio group data");
|
||||||
{
|
|
||||||
if (allSongGroups.find(m_groupId) != allSongGroups.end())
|
/* Build voice engine */
|
||||||
m_sfxGroup = false;
|
std::unique_ptr<boo::IAudioVoiceEngine> voxEngine = boo::NewAudioVoiceEngine();
|
||||||
else if (allSFXGroups.find(m_groupId) != allSFXGroups.end())
|
amuse::BooBackendVoiceAllocator booBackend(*voxEngine);
|
||||||
m_sfxGroup = true;
|
m_engine.emplace(booBackend, amuse::AmplitudeMode::PerSample);
|
||||||
|
|
||||||
|
/* Load group into engine */
|
||||||
|
const amuse::AudioGroup* group = m_engine->addAudioGroup(*selData);
|
||||||
|
if (!group)
|
||||||
|
Log.report(logvisor::Fatal, "unable to add audio group");
|
||||||
|
|
||||||
|
/* Enter playback loop */
|
||||||
|
if (m_sfxGroup)
|
||||||
|
SFXLoop(*sfxIndex);
|
||||||
else
|
else
|
||||||
Log.report(logvisor::Fatal, "unable to find Group %d", m_groupId);
|
SongLoop(*songIndex);
|
||||||
}
|
}
|
||||||
else if (totalGroups > 1)
|
|
||||||
{
|
|
||||||
/* Ask user to specify which group in project */
|
|
||||||
printf("Multiple Audio Groups discovered:\n");
|
|
||||||
for (const auto& pair : allSFXGroups)
|
|
||||||
{
|
|
||||||
printf(" %d %s (SFXGroup) %" PRISize " sfx-entries\n",
|
|
||||||
pair.first, pair.second.first->first.c_str(),
|
|
||||||
pair.second.second->m_sfxEntries.size());
|
|
||||||
}
|
|
||||||
for (const auto& pair : allSongGroups)
|
|
||||||
{
|
|
||||||
printf(" %d %s (SongGroup) %" PRISize " normal-pages, %" PRISize " drum-pages\n",
|
|
||||||
pair.first, pair.second.first->first.c_str(),
|
|
||||||
pair.second.second->m_normPages.size(), pair.second.second->m_drumPages.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
int userSel = 0;
|
|
||||||
printf("Enter Group Number: ");
|
|
||||||
if (scanf("%d", &userSel) <= 0)
|
|
||||||
Log.report(logvisor::Fatal, "unable to parse prompt");
|
|
||||||
|
|
||||||
if (allSongGroups.find(userSel) != allSongGroups.end())
|
|
||||||
{
|
|
||||||
m_groupId = userSel;
|
|
||||||
m_sfxGroup = false;
|
|
||||||
}
|
|
||||||
else if (allSFXGroups.find(userSel) != allSFXGroups.end())
|
|
||||||
{
|
|
||||||
m_groupId = userSel;
|
|
||||||
m_sfxGroup = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Log.report(logvisor::Fatal, "unable to find Group %d", userSel);
|
|
||||||
}
|
|
||||||
else if (totalGroups == 1)
|
|
||||||
{
|
|
||||||
/* Load one and only group */
|
|
||||||
if (allSongGroups.size())
|
|
||||||
{
|
|
||||||
const auto& pair = *allSongGroups.cbegin();
|
|
||||||
m_groupId = pair.first;
|
|
||||||
m_sfxGroup = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto& pair = *allSFXGroups.cbegin();
|
|
||||||
m_groupId = pair.first;
|
|
||||||
m_sfxGroup = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Log.report(logvisor::Fatal, "empty project");
|
|
||||||
|
|
||||||
/* Make final group selection */
|
|
||||||
amuse::IntrusiveAudioGroupData* selData = nullptr;
|
|
||||||
const amuse::SongGroupIndex* songIndex = nullptr;
|
|
||||||
const amuse::SFXGroupIndex* sfxIndex = nullptr;
|
|
||||||
auto songSearch = allSongGroups.find(m_groupId);
|
|
||||||
if (songSearch != allSongGroups.end())
|
|
||||||
{
|
|
||||||
selData = &songSearch->second.first->second;
|
|
||||||
songIndex = songSearch->second.second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto sfxSearch = allSFXGroups.find(m_groupId);
|
|
||||||
if (sfxSearch != allSFXGroups.end())
|
|
||||||
{
|
|
||||||
selData = &sfxSearch->second.first->second;
|
|
||||||
sfxIndex = sfxSearch->second.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selData)
|
|
||||||
Log.report(logvisor::Fatal, "unable to select audio group data");
|
|
||||||
|
|
||||||
/* Build voice engine */
|
|
||||||
std::unique_ptr<boo::IAudioVoiceEngine> voxEngine = boo::NewAudioVoiceEngine();
|
|
||||||
amuse::BooBackendVoiceAllocator booBackend(*voxEngine);
|
|
||||||
m_engine.emplace(booBackend, amuse::AmplitudeMode::BlockLinearized);
|
|
||||||
|
|
||||||
/* Load group into engine */
|
|
||||||
const amuse::AudioGroup* group = m_engine->addAudioGroup(*selData);
|
|
||||||
if (!group)
|
|
||||||
Log.report(logvisor::Fatal, "unable to add audio group");
|
|
||||||
|
|
||||||
/* Enter playback loop */
|
|
||||||
if (m_sfxGroup)
|
|
||||||
SFXLoop(*sfxIndex);
|
|
||||||
else
|
|
||||||
SongLoop(*songIndex);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -800,6 +829,8 @@ void EventCallback::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods,
|
||||||
m_app.m_seq->setVolume(m_app.m_volume);
|
m_app.m_seq->setVolume(m_app.m_volume);
|
||||||
m_app.m_updateDisp = true;
|
m_app.m_updateDisp = true;
|
||||||
break;
|
break;
|
||||||
|
case boo::ESpecialKey::Esc:
|
||||||
|
m_app.m_breakout = true;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,10 @@ public:
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
State m_phase = State::Attack; /**< Current envelope state */
|
State m_phase = State::Attack; /**< Current envelope state */
|
||||||
double m_attackTime = 0.005; /**< Time of attack in seconds */
|
double m_attackTime = 0.02; /**< Time of attack in seconds */
|
||||||
double m_decayTime = 0.0; /**< Time of decay in seconds */
|
double m_decayTime = 0.0; /**< Time of decay in seconds */
|
||||||
double m_sustainFactor = 1.0; /**< Evaluated sustain percentage */
|
double m_sustainFactor = 1.0; /**< Evaluated sustain percentage */
|
||||||
double m_releaseTime = 0.005; /**< Time of release in seconds */
|
double m_releaseTime = 0.02; /**< Time of release in seconds */
|
||||||
double m_releaseStartFactor = 0.0; /**< Level at whenever release event occurs */
|
double m_releaseStartFactor = 0.0; /**< Level at whenever release event occurs */
|
||||||
double m_curTime = 0.0; /**< Current time of envelope stage in seconds */
|
double m_curTime = 0.0; /**< Current time of envelope stage in seconds */
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -13,8 +13,8 @@ namespace amuse
|
||||||
|
|
||||||
Engine::~Engine()
|
Engine::~Engine()
|
||||||
{
|
{
|
||||||
for (std::shared_ptr<Sequencer>& seq : m_activeSequencers)
|
while (m_activeSequencers.size())
|
||||||
seq->_destroy();
|
m_activeSequencers.front()->_destroy();
|
||||||
while (m_activeSubmixes.size())
|
while (m_activeSubmixes.size())
|
||||||
removeSubmix(&m_activeSubmixes.front());
|
removeSubmix(&m_activeSubmixes.front());
|
||||||
for (std::shared_ptr<Emitter>& emitter : m_activeEmitters)
|
for (std::shared_ptr<Emitter>& emitter : m_activeEmitters)
|
||||||
|
@ -308,7 +308,8 @@ std::list<Submix>::iterator Engine::_removeSubmix(Submix* smx)
|
||||||
Submix* ssmx = seq->getSubmix();
|
Submix* ssmx = seq->getSubmix();
|
||||||
if (ssmx == smx)
|
if (ssmx == smx)
|
||||||
{
|
{
|
||||||
seq->_destroy();
|
if (!seq->m_destroyed)
|
||||||
|
seq->_destroy();
|
||||||
it = m_activeSequencers.erase(it);
|
it = m_activeSequencers.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ void Envelope::keyOff()
|
||||||
|
|
||||||
float Envelope::advance(double dt)
|
float Envelope::advance(double dt)
|
||||||
{
|
{
|
||||||
|
double thisTime = m_curTime;
|
||||||
m_curTime += dt;
|
m_curTime += dt;
|
||||||
|
|
||||||
switch (m_phase)
|
switch (m_phase)
|
||||||
|
@ -46,7 +47,7 @@ float Envelope::advance(double dt)
|
||||||
m_releaseStartFactor = 1.f;
|
m_releaseStartFactor = 1.f;
|
||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
double attackFac = m_curTime / m_attackTime;
|
double attackFac = thisTime / m_attackTime;
|
||||||
if (attackFac >= 1.0)
|
if (attackFac >= 1.0)
|
||||||
{
|
{
|
||||||
m_phase = State::Decay;
|
m_phase = State::Decay;
|
||||||
|
@ -66,7 +67,7 @@ float Envelope::advance(double dt)
|
||||||
m_releaseStartFactor = m_sustainFactor;
|
m_releaseStartFactor = m_sustainFactor;
|
||||||
return m_sustainFactor;
|
return m_sustainFactor;
|
||||||
}
|
}
|
||||||
double decayFac = m_curTime / m_decayTime;
|
double decayFac = thisTime / m_decayTime;
|
||||||
if (decayFac >= 1.0)
|
if (decayFac >= 1.0)
|
||||||
{
|
{
|
||||||
m_phase = State::Sustain;
|
m_phase = State::Sustain;
|
||||||
|
@ -88,7 +89,7 @@ float Envelope::advance(double dt)
|
||||||
m_phase = State::Complete;
|
m_phase = State::Complete;
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
double releaseFac = m_curTime / m_releaseTime;
|
double releaseFac = thisTime / m_releaseTime;
|
||||||
if (releaseFac >= 1.0)
|
if (releaseFac >= 1.0)
|
||||||
{
|
{
|
||||||
m_phase = State::Complete;
|
m_phase = State::Complete;
|
||||||
|
|
|
@ -50,7 +50,7 @@ void Sequencer::_destroy()
|
||||||
{
|
{
|
||||||
m_engine.removeSubmix(m_submix);
|
m_engine.removeSubmix(m_submix);
|
||||||
m_submix = nullptr;
|
m_submix = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sequencer::~Sequencer()
|
Sequencer::~Sequencer()
|
||||||
|
|
|
@ -254,12 +254,12 @@ bool Voice::_advanceSample(int16_t& samp, int32_t& newPitch)
|
||||||
if (m_envelopeTime >= 0.0)
|
if (m_envelopeTime >= 0.0)
|
||||||
{
|
{
|
||||||
m_envelopeTime += dt;
|
m_envelopeTime += dt;
|
||||||
float start = m_envelopeStart / 127.f;
|
float start = m_envelopeStart;
|
||||||
float end = m_envelopeEnd / 127.f;
|
float end = m_envelopeEnd;
|
||||||
double t = std::max(0.0, std::min(1.0, m_envelopeTime / m_envelopeDur));
|
float t = std::max(0.f, std::min(1.f, float(m_envelopeTime / m_envelopeDur)));
|
||||||
if (m_envelopeCurve)
|
if (m_envelopeCurve)
|
||||||
t = (*m_envelopeCurve)[int(t*127.f)] / 127.f;
|
t = (*m_envelopeCurve)[int(t*127.f)] / 127.f;
|
||||||
m_curVol = (start * (1.0f - t)) + (end * t);
|
m_curVol = clamp(0.f, (start * (1.0f - t)) + (end * t), 1.f);
|
||||||
|
|
||||||
/* Done with envelope */
|
/* Done with envelope */
|
||||||
if (m_envelopeTime > m_envelopeDur)
|
if (m_envelopeTime > m_envelopeDur)
|
||||||
|
@ -848,7 +848,7 @@ void Voice::setSurroundPan(float span)
|
||||||
|
|
||||||
void Voice::startEnvelope(double dur, float vol, const Curve* envCurve)
|
void Voice::startEnvelope(double dur, float vol, const Curve* envCurve)
|
||||||
{
|
{
|
||||||
m_envelopeTime = m_voiceTime;
|
m_envelopeTime = 0.f;
|
||||||
m_envelopeDur = dur;
|
m_envelopeDur = dur;
|
||||||
m_envelopeStart = clamp(0.f, m_curVol, 1.f);
|
m_envelopeStart = clamp(0.f, m_curVol, 1.f);
|
||||||
m_envelopeEnd = clamp(0.f, vol, 1.f);
|
m_envelopeEnd = clamp(0.f, vol, 1.f);
|
||||||
|
@ -857,7 +857,7 @@ void Voice::startEnvelope(double dur, float vol, const Curve* envCurve)
|
||||||
|
|
||||||
void Voice::startFadeIn(double dur, float vol, const Curve* envCurve)
|
void Voice::startFadeIn(double dur, float vol, const Curve* envCurve)
|
||||||
{
|
{
|
||||||
m_envelopeTime = m_voiceTime;
|
m_envelopeTime = 0.f;
|
||||||
m_envelopeDur = dur;
|
m_envelopeDur = dur;
|
||||||
m_envelopeStart = 0.f;
|
m_envelopeStart = 0.f;
|
||||||
m_envelopeEnd = clamp(0.f, vol, 1.f);
|
m_envelopeEnd = clamp(0.f, vol, 1.f);
|
||||||
|
@ -1018,15 +1018,21 @@ void Voice::setAftertouch(uint8_t aftertouch)
|
||||||
|
|
||||||
void Voice::_notifyCtrlChange(uint8_t ctrl, int8_t val)
|
void Voice::_notifyCtrlChange(uint8_t ctrl, int8_t val)
|
||||||
{
|
{
|
||||||
if (ctrl == 64)
|
if (ctrl == 0x40)
|
||||||
{
|
{
|
||||||
if (val >= 64)
|
if (val >= 0x40)
|
||||||
setPedal(true);
|
setPedal(true);
|
||||||
else
|
else
|
||||||
setPedal(false);
|
setPedal(false);
|
||||||
}
|
}
|
||||||
|
else if (ctrl == 0x41)
|
||||||
|
{
|
||||||
|
printf("PORTAMENTO %d\n", val);
|
||||||
|
}
|
||||||
else if (ctrl == 0x5b)
|
else if (ctrl == 0x5b)
|
||||||
|
{
|
||||||
setReverbVol(val / 127.f);
|
setReverbVol(val / 127.f);
|
||||||
|
}
|
||||||
|
|
||||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
vox->_notifyCtrlChange(ctrl, val);
|
vox->_notifyCtrlChange(ctrl, val);
|
||||||
|
|
Loading…
Reference in New Issue