diff options
author | André Nusser <andre.nusser@googlemail.com> | 2019-07-18 23:42:37 +0200 |
---|---|---|
committer | André Nusser <andre.nusser@googlemail.com> | 2019-07-18 23:44:55 +0200 |
commit | 8877cd2ecd225ddb35a7c21589ad87fdbe0f6dc5 (patch) | |
tree | aed063e436d8f77656dfe44daba86629f72ba7a8 /src/sample_selection.cc | |
parent | 63ca90b25a1c14e8d5082ab7347370e934718b58 (diff) |
Fix issues of sample selection choosing very far samples.
It can still do so, but it is much more unlikely and generally more
stable now.
Diffstat (limited to 'src/sample_selection.cc')
-rw-r--r-- | src/sample_selection.cc | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/sample_selection.cc b/src/sample_selection.cc index fafeda4..03453f3 100644 --- a/src/sample_selection.cc +++ b/src/sample_selection.cc @@ -74,19 +74,26 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) const float f_diverse = settings.sample_selection_f_diverse.load(); const float f_random = settings.sample_selection_f_random.load(); + float const power_range = powerlist.getMaxPower() - powerlist.getMinPower(); + // start with most promising power value and then stop when reaching far values // which cannot become opt anymore auto closest_it = std::lower_bound(samples.begin(), samples.end(), level); std::size_t up_index = std::distance(samples.begin(), closest_it); std::size_t down_index = (up_index == 0 ? 0 : up_index - 1); - float up_value_lb = (up_index < samples.size() ? f_close*pow2(samples[up_index].power-level) : std::numeric_limits<float>::max()); - float down_value_lb = (up_index != 0 ? f_close*pow2(samples[down_index].power-level) : std::numeric_limits<float>::max()); + + auto const close_up = (samples[up_index].power-level)/power_range; + auto const close_down = samples[down_index].power-level/power_range; + float up_value_lb = (up_index < samples.size() ? f_close*pow2(close_up) : std::numeric_limits<float>::max()); + float down_value_lb = (up_index != 0 ? f_close*pow2(close_down) : std::numeric_limits<float>::max()); std::size_t count = 0; do { + DEBUG(rand, "%d %d", (int)up_index, (int)down_index); + // at least avoid infinite loops in case of a bug... - if (count > samples.size()) { break; } + if (up_index == samples.size()-1 && down_index == 0) { break; } std::size_t current_index; if (up_value_lb < down_value_lb) @@ -95,7 +102,7 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) if (up_index != samples.size()-1) { ++up_index; - up_value_lb = f_close*pow2(samples[up_index].power-level); + up_value_lb = f_close*pow2((samples[up_index].power-level)/power_range); } else { @@ -108,7 +115,7 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) if (down_index != 0) { --down_index; - down_value_lb = f_close*pow2(samples[down_index].power-level); + down_value_lb = f_close*pow2((samples[down_index].power-level)/power_range); } else { @@ -117,7 +124,7 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos) } auto random = rand.floatInRange(0.,1.); - auto close = samples[current_index].power - level; + auto close = (samples[current_index].power - level)/power_range; auto diverse = 1./(1. + (float)(pos - last[current_index])/settings.samplerate); auto value = f_close*pow2(close) + f_diverse*pow2(diverse) + f_random*random; |