summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/powerlist.cc382
-rw-r--r--src/powerlist.h39
2 files changed, 224 insertions, 197 deletions
diff --git a/src/powerlist.cc b/src/powerlist.cc
index b6640e9..f94dbb2 100644
--- a/src/powerlist.cc
+++ b/src/powerlist.cc
@@ -53,216 +53,244 @@
PowerList::PowerList()
{
- power_max = 0;
- power_min = 100000000;
- lastsample = NULL;
+ power_max = 0;
+ power_min = 100000000;
+ lastsample = nullptr;
}
#define THRES 1.0
-void PowerList::add(Sample *sample)
+void PowerList::add(Sample* sample)
{
- PowerListItem item;
- item.power = -1;
- item.sample = sample;
+ PowerListItem item;
+ item.power = -1;
+ item.sample = sample;
- samples.push_back(item);
+ samples.push_back(item);
}
-Channel *PowerList::getMasterChannel()
+Channel* PowerList::getMasterChannel()
{
- std::map<Channel *, int> count;
-
- std::vector<PowerListItem>::iterator si = samples.begin();
- while(si != samples.end()) {
- PowerListItem &item = *si;
- Sample *sample = item.sample;
-
- Channel *max_channel = NULL;
- 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()) {
- Channel *c = ai->first;
- AudioFile *af = ai->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--) {
- silence += af->data[s];
- }
- silence /= silence_length;
-
- size_t s = 0;
- for(; s < af->size; s++) {
- float val = af->data[s] * af->data[s] * (1.0 / (float)(s+1));
- if(val > max_val) {
- max_val = val;
- max_channel = c;
- break;
- }
- }
-
- af->unload();
-
- ai++;
- ci++;
- }
-
- if(max_channel) {
- if(count.find(max_channel) == count.end()) count[max_channel] = 0;
- count[max_channel]++;
- }
-
- si++;
- }
-
- Channel *master = NULL;
- int max_count = -1;
-
- std::map<Channel *, int>::iterator ci = count.begin();
- while(ci != count.end()) {
- if(ci->second > max_count &&
- strstr(ci->first->name.c_str(), "Alesis") == 0) {
- master = ci->first;
- max_count = ci->second;
- }
- ci++;
- }
-
- return master;
+ std::map<Channel*, int> count;
+
+ std::vector<PowerListItem>::iterator si = samples.begin();
+ while(si != samples.end())
+ {
+ 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())
+ {
+ Channel* c = ai->first;
+ AudioFile* af = ai->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--)
+ {
+ silence += af->data[s];
+ }
+ silence /= silence_length;
+
+ size_t s = 0;
+ for(; s < af->size; s++)
+ {
+ float val = af->data[s] * af->data[s] * (1.0 / (float)(s + 1));
+ if(val > max_val)
+ {
+ max_val = val;
+ max_channel = c;
+ break;
+ }
+ }
+
+ af->unload();
+
+ ai++;
+ ci++;
+ }
+
+ if(max_channel)
+ {
+ if(count.find(max_channel) == count.end())
+ {
+ count[max_channel] = 0;
+ }
+ count[max_channel]++;
+ }
+
+ si++;
+ }
+
+ Channel* master = nullptr;
+ int max_count = -1;
+
+ std::map<Channel*, int>::iterator ci = count.begin();
+ while(ci != count.end())
+ {
+ if(ci->second > max_count &&
+ strstr(ci->first->name.c_str(), "Alesis") == 0)
+ {
+ master = ci->first;
+ max_count = ci->second;
+ }
+ ci++;
+ }
+
+ return master;
}
void PowerList::finalise()
{
#ifdef AUTO_CALCULATE_POWER
- Channel *master_channel = getMasterChannel();
+ Channel* master_channel = getMasterChannel();
- if(master_channel == NULL) {
- ERR(rand, "No master channel found!\n");
- return; // This should not happen...
- }
+ 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*/
+ 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()) {
- PowerListItem &item = *si;
- Sample *sample = item.sample;
-
- #ifdef AUTO_CALCULATE_POWER
- DEBUG(rand, "Sample: %s\n", sample->name.c_str());
-
- AudioFile *master = NULL;
-
- AudioFiles::iterator afi = sample->audiofiles.begin();
- while(afi != sample->audiofiles.end()) {
- if(afi->first->name == master_channel->name) {
- master = afi->second;
- break;
- }
- afi++;
- }
-
- if(master == NULL) {
- si++;
- continue;
- }
-
- master->load();
-#endif/*AUTO_CALCULATE_POWER*/
+ std::vector<PowerListItem>::iterator si = samples.begin();
+ while(si != samples.end())
+ {
+ PowerListItem& item = *si;
+ Sample* sample = item.sample;
#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++) {
- 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++;
- }
-}
+ DEBUG(rand, "Sample: %s\n", sample->name.c_str());
+
+ AudioFile* master = nullptr;
+
+ AudioFiles::iterator afi = sample->audiofiles.begin();
+ while(afi != sample->audiofiles.end())
+ {
+ if(afi->first->name == master_channel->name)
+ {
+ master = afi->second;
+ break;
+ }
+ afi++;
+ }
+
+ if(master == nullptr)
+ {
+ si++;
+ continue;
+ }
+
+ master->load();
+#endif /*AUTO_CALCULATE_POWER*/
-Sample *PowerList::get(level_t level)
-{
- int retry = 3; // TODO: This must be user controllable via the UI.
-
- Sample *sample = NULL;
+#ifdef AUTO_CALCULATE_POWER
+ if(sample->power == -1)
+ { // Power not defined. Calculate it!
+ DEBUG(powerlist, "Calculating power\n");
- if(!samples.size()) return NULL; // No samples to choose from.
+ float power = 0;
+ size_t s = 0;
+ for(; s < SIZE && s < master->size; s++)
+ {
+ power += master->data[s] * master->data[s];
+ }
- float power_span = power_max - power_min;
+ power = sqrt(power);
- // 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);
+ sample->power = power;
+ }
+#endif /*AUTO_CALCULATE_POWER*/
- // 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;
+ item.power = sample->power;
- // 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);
+ if(item.power > power_max)
+ power_max = item.power;
+ if(item.power < power_min)
+ power_min = item.power;
-again:
- // Select normal distributed value between
- // (stddev/2) and (power_span-stddev/2)
- float lvl = rand.normalDistribution(mean, stddev);
+ DEBUG(rand, " - power: %f\n", item.power);
- // Adjust this value to be in range
- // (power_min+stddev/2) and (power_max-stddev/2)
- lvl += power_min;
+ si++;
+ }
+}
- DEBUG(rand, "level: %f, lvl: %f (mean: %.2f, stddev: %.2f)\n",
- level, lvl, mean, stddev);
+Sample* PowerList::get(level_t level)
+{
+ int retry = 3; // TODO: This must be user controllable via the UI.
- float power = 0;
- std::vector<PowerListItem>::iterator i = samples.begin();
- while(i != samples.end()) {
- if(sample == NULL) {
- sample = i->sample;
- power = i->power;
- }
+ Sample* sample = nullptr;
- if(fabs(i->power - lvl) < fabs(power - lvl)) {
- sample = i->sample;
- power = i->power;
- }
+ if(!samples.size())
+ {
+ return nullptr; // No samples to choose from.
+ }
- i++;
- }
+ float power_span = power_max - power_min;
- if(lastsample == sample && retry--) {
- DEBUG(rand, "Retry [%d retries left]", retry);
- goto again;
- }
+ // 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);
- DEBUG(rand, "Found sample with power %f\n", power);
+ // 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;
- lastsample = sample;
+ // 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);
- return sample;
+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())
+ {
+ if(sample == nullptr)
+ {
+ sample = i->sample;
+ power = i->power;
+ }
+
+ if(fabs(i->power - lvl) < fabs(power - lvl))
+ {
+ sample = i->sample;
+ power = i->power;
+ }
+
+ i++;
+ }
+
+ if(lastsample == sample && retry--)
+ {
+ DEBUG(rand, "Retry [%d retries left]", retry);
+ goto again;
+ }
+
+ DEBUG(rand, "Found sample with power %f\n", power);
+
+ lastsample = sample;
+
+ return sample;
}
diff --git a/src/powerlist.h b/src/powerlist.h
index 1077d8c..a3af475 100644
--- a/src/powerlist.h
+++ b/src/powerlist.h
@@ -24,38 +24,37 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __DRUMGIZMO_POWERLIST_H__
-#define __DRUMGIZMO_POWERLIST_H__
+#pragma once
#include <vector>
#include "sample.h"
#include "random.h"
-class PowerList {
+class PowerList
+{
public:
- PowerList();
+ PowerList();
- void add(Sample *s);
- void finalise(); ///< Call this when no more samples will be added.
+ void add(Sample* s);
+ void finalise(); ///< Call this when no more samples will be added.
- Sample *get(level_t velocity);
+ Sample* get(level_t velocity);
private:
- class PowerListItem {
- public:
- Sample *sample;
- float power;
- };
+ class PowerListItem
+ {
+ public:
+ Sample* sample;
+ float power;
+ };
- Random rand;
+ Random rand;
- std::vector<PowerListItem> samples;
- float power_max;
- float power_min;
+ std::vector<PowerListItem> samples;
+ float power_max;
+ float power_min;
- Channel *getMasterChannel();
- Sample *lastsample;
+ Channel* getMasterChannel();
+ Sample* lastsample;
};
-
-#endif/*__DRUMGIZMO_POWERLIST_H__*/