diff options
| author | Christian Glöckner <cgloeckner@freenet.de> | 2016-03-29 17:30:15 +0200 | 
|---|---|---|
| committer | André Nusser <andre.nusser@googlemail.com> | 2016-03-31 17:48:37 +0200 | 
| commit | 852b31481189d6ff9e490533a598ee5154a044f5 (patch) | |
| tree | cb950ce71f9c5ae35460d7c6d96ad622d7a61e21 /src | |
| parent | e03a52fe134e386c543bc1a83e21114ecedb7561 (diff) | |
Reformatted class PowerList
Diffstat (limited to 'src')
| -rw-r--r-- | src/powerlist.cc | 382 | ||||
| -rw-r--r-- | src/powerlist.h | 39 | 
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__*/ | 
