summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/powerlist.cc212
-rw-r--r--src/powerlist.h7
2 files changed, 93 insertions, 126 deletions
diff --git a/src/powerlist.cc b/src/powerlist.cc
index 8fec8ce..4aa916a 100644
--- a/src/powerlist.cc
+++ b/src/powerlist.cc
@@ -44,12 +44,13 @@
* Limited by sample set size, ie. only kicks in if sample set size is smaller
* than this number.
*/
-#define MIN_SAMPLE_SET_SIZE 26
+unsigned int const MIN_SAMPLE_SET_SIZE = 26u;
// Enable to calculate power on old samples without power attribute
//#define AUTO_CALCULATE_POWER
+unsigned int const SIZE = 500u;
-#define SIZE 500
+float const THRES = 1.f;
PowerList::PowerList(Random& rand)
: rand(rand)
@@ -59,8 +60,6 @@ PowerList::PowerList(Random& rand)
lastsample = nullptr;
}
-#define THRES 1.0
-
void PowerList::add(Sample* sample)
{
PowerListItem item;
@@ -73,38 +72,29 @@ void PowerList::add(Sample* sample)
Channel* PowerList::getMasterChannel()
{
std::map<Channel*, int> count;
-
- std::vector<PowerListItem>::iterator si = samples.begin();
- while(si != samples.end())
+
+ for (auto& item: samples)
{
- PowerListItem& item = *si;
- Sample* sample = item.sample;
-
- Channel* max_channel = nullptr;
- sample_t max_val = 0;
-
- // DEBUG(rand, "Sample: %s\n", sample->name.c_str());
-
- size_t ci = 0;
- AudioFiles::iterator ai = sample->audiofiles.begin();
- while(ai != sample->audiofiles.end())
+ Sample* sample{item.sample};
+ Channel* max_channel{nullptr};
+ sample_t max_val{0};
+
+ for (auto& pair: sample->audiofiles)
{
- Channel* c = ai->first;
- AudioFile* af = ai->second;
-
+ Channel* c = pair.first;
+ AudioFile* af = pair.second;
+
af->load(SIZE);
-
- float silence = 0;
- size_t silence_length = 4;
- for(size_t s = af->size; s > 0 && s > af->size - silence_length;
- s--)
+
+ float silence{0.f};
+ std::size_t silence_length{4u};
+ for (auto s = af->size; s > 0 && s > af->size - silence_length; --s)
{
silence += af->data[s];
}
silence /= silence_length;
-
- size_t s = 0;
- for(; s < af->size; s++)
+
+ for(auto s = 0u; s < af->size; ++s)
{
float val = af->data[s] * af->data[s] * (1.0 / (float)(s + 1));
if(val > max_val)
@@ -114,11 +104,8 @@ Channel* PowerList::getMasterChannel()
break;
}
}
-
+
af->unload();
-
- ai++;
- ci++;
}
if(max_channel)
@@ -127,27 +114,22 @@ Channel* PowerList::getMasterChannel()
{
count[max_channel] = 0;
}
- count[max_channel]++;
+ ++count[max_channel];
}
-
- si++;
}
-
- Channel* master = nullptr;
- int max_count = -1;
-
- std::map<Channel*, int>::iterator ci = count.begin();
- while(ci != count.end())
+
+ Channel* master{nullptr};
+ int max_count{-1};
+
+ for (auto& pair: count)
{
- if(ci->second > max_count &&
- strstr(ci->first->name.c_str(), "Alesis") == 0)
+ if (pair.second > max_count && pair.first->name.find("Alesis") == 0u)
{
- master = ci->first;
- max_count = ci->second;
+ master = pair.first;
+ max_count = pair.second;
}
- ci++;
}
-
+
return master;
}
@@ -155,143 +137,129 @@ void PowerList::finalise()
{
#ifdef AUTO_CALCULATE_POWER
Channel* master_channel = getMasterChannel();
-
+
if(master_channel == nullptr)
{
ERR(rand, "No master channel found!\n");
return; // This should not happen...
}
-
+
DEBUG(rand, "Master channel: %s\n", master_channel->name.c_str());
#endif /*AUTO_CALCULATE_POWER*/
-
- std::vector<PowerListItem>::iterator si = samples.begin();
- while(si != samples.end())
+
+ for (auto& item: samples)
{
- PowerListItem& item = *si;
Sample* sample = item.sample;
-
#ifdef AUTO_CALCULATE_POWER
DEBUG(rand, "Sample: %s\n", sample->name.c_str());
-
- AudioFile* master = nullptr;
-
- AudioFiles::iterator afi = sample->audiofiles.begin();
- while(afi != sample->audiofiles.end())
+
+ AudioFile* master{nullptr};
+
+ for (auto& af: sample->audiofiles)
{
- if(afi->first->name == master_channel->name)
+ if (af.first->name == master_channel->name)
{
- master = afi->second;
+ master = af.second;
break;
}
- afi++;
}
-
+
if(master == nullptr)
{
- si++;
continue;
}
-
+
master->load();
#endif /*AUTO_CALCULATE_POWER*/
-
+
#ifdef AUTO_CALCULATE_POWER
if(sample->power == -1)
{ // Power not defined. Calculate it!
DEBUG(powerlist, "Calculating power\n");
- float power = 0;
- size_t s = 0;
- for(; s < SIZE && s < master->size; s++)
+ float power{0.f};
+ for(auto s = 0u; s < SIZE && s < master->size; ++s)
{
power += master->data[s] * master->data[s];
}
-
+
power = sqrt(power);
-
+
sample->power = power;
}
#endif /*AUTO_CALCULATE_POWER*/
-
+
item.power = sample->power;
-
+
if(item.power > power_max)
+ {
power_max = item.power;
+ }
if(item.power < power_min)
+ {
power_min = item.power;
-
+ }
+
DEBUG(rand, " - power: %f\n", item.power);
-
- si++;
}
}
Sample* PowerList::get(level_t level)
{
- int retry = 3; // TODO: This must be user controllable via the UI.
-
- Sample* sample = nullptr;
-
if(!samples.size())
{
return nullptr; // No samples to choose from.
}
-
+
+ int retry = 3; // TODO: This must be user controllable via the UI.
+
+ Sample* sample{nullptr};
+
float power_span = power_max - power_min;
-
+
// Width is limited to at least 10. Fioxes problem with instrument with a
// sample set smaller than MIN_SAMPLE_SET_SIZE.
float width = fmax(samples.size(), MIN_SAMPLE_SET_SIZE);
-
+
// Spread out at most ~2 samples away from center if all samples have a
// uniform distribution over the power spectrum (which they probably don't).
float stddev = power_span / width;
-
+
// Cut off mean value with stddev/2 in both ends in order to make room for
// downwards expansion on velocity 0 and upwards expansion on velocity 1.
float mean = level * (power_span - stddev) + (stddev / 2.0);
-
-again:
- // Select normal distributed value between
- // (stddev/2) and (power_span-stddev/2)
- float lvl = rand.normalDistribution(mean, stddev);
-
- // Adjust this value to be in range
- // (power_min+stddev/2) and (power_max-stddev/2)
- lvl += power_min;
-
- DEBUG(rand, "level: %f, lvl: %f (mean: %.2f, stddev: %.2f)\n", level, lvl,
- mean, stddev);
-
- float power = 0;
- std::vector<PowerListItem>::iterator i = samples.begin();
- while(i != samples.end())
+
+ float power{0.f};
+
+ // note: loop is executed once + #retry
+ do
{
- if(sample == nullptr)
- {
- sample = i->sample;
- power = i->power;
- }
-
- if(fabs(i->power - lvl) < fabs(power - lvl))
+ --retry;
+
+ // Select normal distributed value between
+ // (stddev/2) and (power_span-stddev/2)
+ float lvl = rand.normalDistribution(mean, stddev);
+
+ // Adjust this value to be in range
+ // (power_min+stddev/2) and (power_max-stddev/2)
+ lvl += power_min;
+
+ DEBUG(rand, "level: %f, lvl: %f (mean: %.2f, stddev: %.2f)\n", level, lvl,
+ mean, stddev);
+
+ for (auto& item: samples)
{
- sample = i->sample;
- power = i->power;
+ if (sample == nullptr || std::fabs(item.power - lvl) < std::fabs(power - lvl))
+ {
+ sample = item.sample;
+ power = item.power;
+ }
}
-
- i++;
- }
-
- if(lastsample == sample && retry--)
- {
- DEBUG(rand, "Retry [%d retries left]", retry);
- goto again;
- }
-
+ } while (lastsample == sample && retry >= 0);
+
DEBUG(rand, "Found sample with power %f\n", power);
-
+
lastsample = sample;
-
+
return sample;
}
diff --git a/src/powerlist.h b/src/powerlist.h
index 53a42b8..ff360b4 100644
--- a/src/powerlist.h
+++ b/src/powerlist.h
@@ -38,13 +38,12 @@ public:
void add(Sample* s);
void finalise(); ///< Call this when no more samples will be added.
-
+
Sample* get(level_t velocity);
private:
- class PowerListItem
+ struct PowerListItem
{
- public:
Sample* sample;
float power;
};
@@ -54,7 +53,7 @@ private:
std::vector<PowerListItem> samples;
float power_max;
float power_min;
-
+
Channel* getMasterChannel();
Sample* lastsample;
};