diff --git a/include/InstrumentFunctions.h b/include/InstrumentFunctions.h index ae8a8d3398b..e9dbd196381 100644 --- a/include/InstrumentFunctions.h +++ b/include/InstrumentFunctions.h @@ -181,6 +181,7 @@ class InstrumentFunctionArpeggio : public Model, public JournallingObject enum ArpRandomDistributions { + ArpRandomBase, ArpRandomExp, ArpRandomNormal, ArpRandomChase, diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index 26dc34eb6ab..cfef4b9f3d0 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -326,6 +326,7 @@ InstrumentFunctionArpeggio::InstrumentFunctionArpeggio( Model * _parent ) : m_arpDirectionModel.addItem( tr( "Random" ), std::make_unique( "arp_random" ) ); m_arpDirectionModel.setInitValue( ArpDirUp ); + m_arpRandomModel.addItem(tr("Base"), std::make_unique("arp_random")); m_arpRandomModel.addItem(tr("Exponential"), std::make_unique("arp_random")); m_arpRandomModel.addItem(tr("Normal"), std::make_unique("arp_random")); m_arpRandomModel.addItem(tr("Chase"), std::make_unique("arp_random")); @@ -503,20 +504,25 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) // If direction is ArpDirDownUp the result is inverted if( dir == ArpDirDownAndUp ){ cur_arp_idx = (range/repeats) - cur_arp_idx - 1; } } - else // All randomness from here on + else if(dir == ArpDirRandom) { int randomness = m_arpRandomModel.value(); + int randRange = range / repeats; float shape = m_arpRandShapeModel.value(); bool isNeg = shape < 0.0f; shape = std::fabs(shape); shape = shape < 1.0f ? 1.0f : shape; float randNumber = 0.0f; - if (randomness == ArpRandomExp) // Exponential response (default) + if (randomness == ArpRandomBase) // Exponential response (default) + { + cur_arp_idx = fast_rand() % randRange; + } + else if (randomness == ArpRandomExp) // Exponential response (default) { randNumber = fastRandf(1.0f); - cur_arp_idx = static_cast(range * std::pow(randNumber, shape)); - if (!isNeg){ cur_arp_idx = range - cur_arp_idx - 1; } + cur_arp_idx = static_cast(randRange * std::pow(randNumber, shape)); + if (!isNeg){ cur_arp_idx = randRange - cur_arp_idx - 1; } } else if (randomness == ArpRandomNormal) // Normal distribution/inverted normal distribution { @@ -528,25 +534,24 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) if (isNeg){ randNumber += randNumber > 0.5f ? -0.5f : 0.5f; } - cur_arp_idx = static_cast(randNumber * range); + cur_arp_idx = static_cast(randNumber * randRange); } else if (randomness == ArpRandomChase) // Chase - Brownian motion { randNumber = fastRandf(1.0f); float shape2 = fabs(m_arpRandShapeModel.value()); int change = static_cast(shape2 - std::round(2 * shape2 * randNumber)); - change *= repeats; cur_arp_idx = m_lastRandomNote + change; if (!isNeg) { // cur_arp_idx = std::clamp(cur_arp_idx, 0, range - 1); // gnu++17 - cur_arp_idx = std::min(cur_arp_idx, range - 1); + cur_arp_idx = std::min(cur_arp_idx, randRange - 1); cur_arp_idx = std::max(cur_arp_idx, 0); } else { - cur_arp_idx += cur_arp_idx < 0 ? range : 0; - cur_arp_idx -= cur_arp_idx > range - 1 ? range : 0; + cur_arp_idx += cur_arp_idx < 0 ? randRange : 0; + cur_arp_idx -= cur_arp_idx > randRange - 1 ? randRange : 0; } m_lastRandomNote = cur_arp_idx; }